XML (Extensible Markup Language)

Extensible Markup Language (XML) is a meta-markup language that provides a format for describing structured data. This facilitates more precise declarations of content and more meaningful search results across multiple platforms. In addition, XML is enabling a new generation of Web-based data viewing and manipulation applications.

Main Components of the XML SDK Documentation

XML Developer's Guide

This section of the Microsoft® XML SDK documentation contains information about getting started with XML, as well as using the Document Object Model (DOM).

XML Schemas

This section contains information about creating XML Schemas.

XML Reference

This section contains reference topics for each DOM object and corresponding interface, each method, property, event, and enumeration in the DOM. It also includes topics about XML errors, schema, and data types.

XML Tutorial

This section contains a set of interactive lessons that demonstrate XML authoring and development tasks.

XSLT Developer's Guide

This section contains information about using XSL Transformations (XSLT).

XSLT Reference

This section contains reference topics for XSLT elements, methods, and pattern syntax.

XML and XSL Samples

This section lists samples that are available on MSDN® Online.

SAX2 Developer's Guide

This section contains introductory information about Microsoft's Component Object Model (COM) implementation of the latest version of the Simple API for XML, SAX2.

SAX2 Reference

This section contains reference topics for each SAX2 interface, including interfaces for both Microsoft Visual Basic® and C++.

Feedback

Send error reports, feature requests, and comments about the XML documentation or samples directly to the Microsoft XML documentation team.

See Also

  • Microsoft Data Access Components (MDAC)
  • Web Services, part of the Platform SDK documentation


What's New

The Microsoft® XML Parser (MSXML) 4.0 Technology Preview provides the following new features that are not available in previous production releases of MSXML.

Feature For more information
XML Schema Definition (XSD) Support

The XSD implementation provided with the MSXML 4.0 Technology Preview conforms to the World Wide Web Consortium (W3C) Proposed Recommendation, 16 March 2001. The MSXML 4.0 Technology Preview does not support regular expressions and identity constraints.

 Getting Started with XML Schemas

XML Schema Reference (XSD)
XML Path Language (XPath) Extension Functions for XSD Support

Since the XPath 1.0 syntax does not support expressions that evaluate nodes based on data type, MSXML 4.0 offers a number of XPath extension functions that do just that.

MSXML 4.0 also provides several other XPath extension functions, such as:

  • string-compare for lexicographical string comparison
  • format-date and format-time which convert standard XSD date/time formats to characters suitable for output
 Microsoft XPath Extension Functions
IMXNamespaceManager and IMXNamespacePrefixes Interfaces

These two new interfaces offer a convenient way to manage namespaces, namespace prefixes, and namespace URIs.

 IMXNamespaceManager Interface

IMXNamespacePrefixes Interface
SAX to DOM Support

MSXML 4.0 provides the ability to integrate DOM objects into Simple API for XML (SAX) applications. With the SAX IMXWriter interface, you can now create a DOMDocument object from SAX events by setting the output property of IMXWriter to a DOMDocument object.

 Create a DOMDocument Object from SAX Events

IMXWriter Interface
DOM to SAX Support

MSXML 4.0 provides the ability to create SAX applications that throw SAX events from a DOMDocument object. Throwing SAX events from a DOMDocument object is as simple providing a DOMDocument object as the input parameter of the Parse method of ISAXXMLReader interface.

 Throw SAX Events from a DOMDocument Object

IMXWriter Interface
MXHTMLWriter

The MXHTMLWriter coclass, an implementation of the IMXWriter interface, makes it possible to generate HTML output from SAX applications. MXHTMLWriter follows the same rules for generating HTML output as are defined for <xsl:output> when the method attribute is set to "html".

 MXHTML Writer Coclass MXHTMLWriter

IMXWriter Interface
Wizard for Creating C++ SAX Applications

The SAX Win32 AppWizard, available for download from Microsoft® Product Support Services, facilitates programming SAX applications in C++. Included with the download is a sample program created using this wizard.

 SAX C++ Wizard
Improved IServerXMLHTTPRequest Samples

Based on customer requests, several new samples have been added to the IServerXMLHTTPRequest documentation. These samples demonstrate how to:

  • Use the ServerXMLHTTP object by using the setProperty method of DOMDocument.
  • Receive XML documents from an ASP page on a local or remote Web server (HTTP GET).
  • Post XML documents to an ASP page on a local or remote Web server (HTTP POST).
  • Post and process response XML documents from an ASP page (HTTP POST).
 IServerXMLHTTPRequest/ServerXMLHTTP Examples
Enhanced XSLT Development Guide

Based on customer requests, the XSLT Developer's Guide has been enhanced with a variety of new topics.

 XSLT Developer's Guide

Using XSLT Variables and Parameters

Working with Namespaces and Prefix Aliases

Using msxsl:node-set() to Process Result-Tree Fragments
New GUIDs and PROGIDs

MSXML 4.0 provides three DLL files that are installed in your system folder upon downloading the parser: msxml4.dll, msxml4a.dll, and msxml4r.dll. The names for the header (msxml2.h), .lib (msxml2.lib), and .idl (msxml2.idl.) files remain the same for this release.

 GUID and ProgID Information


Installing and Registering the MSXML 4.0 Technology Preview

The Microsoft XML Parser (MSXML) 4.0 Technology Preview is installed on your computer in side-by-side mode. This mode protects the quality of applications that currently use the msxml.dll, msxml2.dll, or msxml3.dll files. Side-by-side mode also allows you to decide which version of the parser to use in your code. When you install the MSXML 4.0 Technology Preview from the Microsoft XML Download Center, the setup program downloads three files, msxml4.dll, msxml4a.dll, and msxml4r.dll, onto your computer and registers the msxml4.dll file in the computer's registry.

Note The MSXML 4.0 Technology Preview does not provide an xmlinst.exe utility.

After you install the MSXML 4.0 Technology Preview, calling applications using version-independent CLSIDs and ProgIDs will reference msxml4.dll. To ensure stability in your applications, however, it is recommended that you use version-dependent CLSIDs and ProgIDs. For a list of CLSIDs and ProgIDs, see GUID and ProgID Information.

A Caution Against Mixing Version-Dependent and Version-Independent CLSIDs and ProgIDs

When building applications, make certain that you don't mix version-independent and version-dependent CLSIDs or ProgIDs. Using both version-dependent and version-independent CLSIDs or ProgIDs in your code can cause problems with your application. To ensure stability in your applications, it is recommended that you use version-dependent CLSIDs or ProgIDs.

See Also Other Resources

XML Development Center


GUID and ProgID Information

The Microsoft® XML Parser (MSXML) 4.0 Technology Preview is installed on your computer in side-by-side mode, which means installing MSXML 4.0 does not replace any previously installed version of the parser on your computer. This is done to protect the quality of your applications that are currently using msxml.dll, msxml2.dll, or msxml3.dll, as well as allowing you to decide which version of the parser to use in your code.

After you install the MSXML 4.0 Technology Preview, calling applications using version-independent CLSIDs and ProgIDs will reference msxml4.dll. To ensure stability in your applications, however, it is recommended that you use version-dependent CLSIDs and ProgIDs.

MSXML 4.0 GUIDs and ProgIDs

Version Dependent

Symbolic Name | GUID | ProgID
CLSID_DOMDocument40 | {88d969c0-f192-11d4-a65f-0040963251e5} | Msxml2.DOMDocument40
CLSID_FreeThreadedDOMDocument40 | {88d969c1-f192-11d4-a65f-0040963251e5} | Msxml2.FreeThreadedDOMDocument.4.0
CLSID_DSOControl40 | {88d969c4-f192-11d4-a65f-0040963251e5} | Msxml2.DSOControl.4.0
CLSID_XMLHTTP40 | {88d969c5-f192-11d4-a65f-0040963251e5} | Msxml2.XMLHTTP.4.0
CLSID_XMLSchemaCache40 | {88d969c2-f192-11d4-a65f-0040963251e5} | Msxml2.XMLSchemaCache.4.0
CLSID_XMLDOMXSLTemplate40 | {88d969c3-f192-11d4-a65f-0040963251e5} | Msxml2.XMLDOMXSLTemplate.4.0
CLSID_SAXAttributes40 | {88d969ca-f192-11d4-a65f-0040963251e5} | Msxml2.SAXAttributes4.0
CLSID_SAXXMLReader40 | {88d969c7-f192-11d4-a65f-0040963251e5 | Msxml2.SAXXMLReader4.0
CLSID_MXXMLWriter40 | {88d969c8-f192-11d4-a65f-0040963251e5} | Msxml2.MXXMLWriter4.0
CLSID_MXHTMLWriter40 | {88d969c9-f192-11d4-a65f-0040963251e5} | Msxml2.MXHTMLWriter4.0
CLSID_MXNamespaceManager40 | {88d969d6-f192-11d4-a65f-0040963251e5} | Msxml2. MXNamespaceManager40

Version Independent

Symbolic Name | GUID | ProgID
CLSID_DOMDocument | {f6d90f11-9c73-11d3-b32e-00c04f990bb4} | Msxml2.DOMDocument
CLSID_FreeThreadedDOMDocument | {f6d90f12-9c73-11d3-b32e-00c04f990bb4} | Msxml2.FreeThreadedDOMDocument
CLSID_DSOControl | {f6d90f14-9c73-11d3-b32e-00c04f990bb4} | Msxml2.DSOControl
CLSID_XMLHTTP | {f6d90f16-9c73-11d3-b32e-00c04f990bb4} | Msxml2.XMLHTTP
CLSID_XMLSchemaCache | {373984C9-B845-449B-91E7-45AC83036ADE} | Msxml2.XMLSchemaCache
CLSID_XSLTemplate | {2933BF94-7B36-11d2-B20E-00C04F983E60} | Msxml2.XSLTemplate
CLSID_SAXAttributes | {4dd441ad-526d-4a77-9f1b-9841ed802fb0} | Msxml2.SAXAttributes
CLSID_SAXXMLReader | {079aa557-4a18-424a-8eee-e39f0a8d41b9} | Msxml2.SAXXMLReader
CLSID_MXXMLWriter | {fc220ad8-a72a-4ee8-926e-0b7ad152a020} | Msxml2.MXXMLWriter
CLSID_MXHTMLWriter | {a4c23ec3-6b70-4466-9127-550077239978} | Msxml2.MXHTMLWriter
CLSID_MXNamespaceManager | {88d969d5-f192-11d4-a65f-0040963251e5} | Msxml2.MXNamespaceManager

MSXML 3.0 GUIDs and ProgIDs

Version Dependent

Symbolic Name | GUID | ProgID
CLSID_DOMDocument30 | {f5078f32-c551-11d3-89b9-0000f81fe221} | Msxml2.DOMDocument.3.0
CLSID_FreeThreadedDOMDocument30 | {f5078f33-c551-11d3-89b9-0000f81fe221} | Msxml2.FreeThreadedDOMDocument.3.0
CLSID_DSOControl30 | {f5078f39-c551-11d3-89b9-0000f81fe221} | Msxml2.DSOControl.3.0
CLSID_XMLHTTP30 | {f5078f35-c551-11d3-89b9-0000f81fe221} | Msxml2.XMLHTTP.3.0
CLSID_XMLSchemaCache30 | {f5078f34-c551-11d3-89b9-0000f81fe221} | Msxml2.XMLSchemaCache.3.0
CLSID_XSLTemplate30 | {f5078f36-c551-11d3-89b9-0000f81fe221} | Msxml2.XSLTemplate.3.0
CLSID_SAXAttributes30 | {3e784a01-f3ae-4dc0-9354-9526b9370eba} | Msxml2.SAXAttributes3.0
CLSID_SAXXMLReader40 | {3124c396-fb13-4836-a6ad-1317f1713688} | Msxml2.SAXXMLReader3.0
CLSID_MXXMLWriter30 | {3d813dfe-6c91-4a4e-8f41-04346a841d9c} | Msxml2.MXXMLWriter3.0
CLSID_MXHTMLWriter30 | {853d1540-c1a7-4aa9-a226-4d3bd301146d} | Msxml2.MXHTMLWriter3.0

Version Independent

Symbolic Name | GUID | ProgID
CLSID_DOMDocument | {f6d90f11-9c73-11d3-b32e-00c04f990bb4} | Msxml2.DOMDocument
CLSID_FreeThreadedDOMDocument | {f6d90f12-9c73-11d3-b32e-00c04f990bb4} | Msxml2.FreeThreadedDOMDocument
CLSID_DSOControl | {f6d90f14-9c73-11d3-b32e-00c04f990bb4} | Msxml2.DSOControl
CLSID_XMLHTTP | {f6d90f16-9c73-11d3-b32e-00c04f990bb4} | Msxml2.XMLHTTP
CLSID_XMLSchemaCache | {373984C9-B845-449B-91E7-45AC83036ADE} | Msxml2.XMLSchemaCache
CLSID_XSLTemplate | {2933BF94-7B36-11d2-B20E-00C04F983E60} | Msxml2.XSLTemplate
CLSID_SAXAttributes | {4dd441ad-526d-4a77-9f1b-9841ed802fb0} | Msxml2.SAXAttributes
CLSID_SAXXMLReader | {079aa557-4a18-424a-8eee-e39f0a8d41b9} | Msxml2.SAXXMLReader
CLSID_MXXMLWriter | {fc220ad8-a72a-4ee8-926e-0b7ad152a020} | Msxml2.MXXMLWriter
CLSID_MXHTMLWriter | {a4c23ec3-6b70-4466-9127-550077239978} | Msxml2.MXHTMLWriter


Using Language Filtering

The Microsoft XML SDK documentation allows you to display only the information that is relevant to your programming environment, for example, Microsoft® Visual Basic®, C/C++, or script. To use this language filtering functionality, click the Language Filter button Language Filter in the upper-left corner of the title bar. From the Language menu, select the language. Information that pertains to all languages will be displayed regardless of the language option you select.

Note After a language filtering option is selected, that selection is persisted until you change the option.


Sample XML File (books.xml)

The following XML file is used throughout the Microsoft XML SDK, except where noted.

<?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications
      with XML.</description>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies,
      an evil sorceress, and her own childhood to become queen
      of the world.</description>
   </book>
   <book id="bk103">
      <author>Corets, Eva</author>
      <title>Maeve Ascendant</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-11-17</publish_date>
      <description>After the collapse of a nanotechnology
      society in England, the young survivors lay the
      foundation for a new society.</description>
   </book>
   <book id="bk104">
      <author>Corets, Eva</author>
      <title>Oberon's Legacy</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2001-03-10</publish_date>
      <description>In post-apocalypse England, the mysterious
      agent known only as Oberon helps to create a new life
      for the inhabitants of London. Sequel to Maeve
      Ascendant.</description>
   </book>
   <book id="bk105">
      <author>Corets, Eva</author>
      <title>The Sundered Grail</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2001-09-10</publish_date>
      <description>The two daughters of Maeve, half-sisters,
      battle one another for control of England. Sequel to
      Oberon's Legacy.</description>
   </book>
   <book id="bk106">
      <author>Randall, Cynthia</author>
      <title>Lover Birds</title>
      <genre>Romance</genre>
      <price>4.95</price>
      <publish_date>2000-09-02</publish_date>
      <description>When Carla meets Paul at an ornithology
      conference, tempers fly as feathers get ruffled.</description>
   </book>
   <book id="bk107">
      <author>Thurman, Paula</author>
      <title>Splish Splash</title>
      <genre>Romance</genre>
      <price>4.95</price>
      <publish_date>2000-11-02</publish_date>
      <description>A deep sea diver finds true love twenty
      thousand leagues beneath the sea.</description>
   </book>
   <book id="bk108">
      <author>Knorr, Stefan</author>
      <title>Creepy Crawlies</title>
      <genre>Horror</genre>
      <price>4.95</price>
      <publish_date>2000-12-06</publish_date>
      <description>An anthology of horror stories about roaches,
      centipedes, scorpions  and other insects.</description>
   </book>
   <book id="bk109">
      <author>Kress, Peter</author>
      <title>Paradox Lost</title>
      <genre>Science Fiction</genre>
      <price>6.95</price>
      <publish_date>2000-11-02</publish_date>
      <description>After an inadvertant trip through a Heisenberg
      Uncertainty Device, James Salway discovers the problems
      of being quantum.</description>
   </book>
   <book id="bk110">
      <author>O'Brien, Tim</author>
      <title>Microsoft .NET: The Programming Bible</title>
      <genre>Computer</genre>
      <price>36.95</price>
      <publish_date>2000-12-09</publish_date>
      <description>Microsoft's .NET initiative is explored in
      detail in this deep programmer's reference.</description>
   </book>
   <book id="bk111">
      <author>O'Brien, Tim</author>
      <title>MSXML3: A Comprehensive Guide</title>
      <genre>Computer</genre>
      <price>36.95</price>
      <publish_date>2000-12-01</publish_date>
      <description>The Microsoft MSXML3 parser is covered in
      detail, with attention to XML DOM interfaces, XSLT processing,
      SAX and more.</description>
   </book>
   <book id="bk112">
      <author>Galos, Mike</author>
      <title>Visual Studio 7: A Comprehensive Guide</title>
      <genre>Computer</genre>
      <price>49.95</price>
      <publish_date>2001-04-16</publish_date>
      <description>Microsoft Visual Studio 7 is explored in depth,
      looking at how Visual Basic, Visual C++, C#, and ASP+ are
      integrated into a comprehensive development
      environment.</description>
   </book>
</catalog>


Copyright and Legal Information

This is a preliminary document and may be changed substantially prior to final commercial release. This document is provided for informational purposes only and Microsoft makes no warranties, either express or implied, in this document. Information in this document, including URL and other Internet Web site references, is subject to change without notice. The entire risk of the use or the results of the use of this document remains with the user. Unless otherwise noted, the example companies, organizations, products, domain names, email addresses, logos, people, places and events depicted herein are fictitious, and no association with any real company, organization, product, domain name, email address, logo, person, places or events is intended or should be inferred. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

© 2001 Microsoft Corporation. All rights reserved.

Microsoft, MS-DOS, Windows, Windows NT, Visual Studio, Visual C++, and Visual Basic are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.

The names of actual companies and products mentioned herein may be the trademarks of their respective owners.


XML Developer's Guide

The XML Developer's Guide includes these sections.

  • Introduction to XML
  • XML Fundamentals
  • XML DOM User Guide
  • XML Tutorial
  • Using XML on the Server
  • XML and Security
  • Binding the XML Data Source Object to Data

See Also

XML Reference | XML Error Messages


Introduction to XML

On the surface, XML looks like HTML. Both are derived from the Standard Generalized Markup Language (SGML). Tools that generate HTML can often be reused to generate XML.

XML is different from HTML in two key areas: syntax and semantics.

XML Syntax for Well-formed Documents

Both HTML and XML use <, >, and & to create element and attribute structures. While HTML browsers accept or ignore mangled markup language, XML parsers and applications built on those parsers are less forgiving. Errors in XML syntax halt document processing, and users or applications receive error messages, not a best-guess interpretation of the document structure.

XML documents must be well-formed. That is, they must follow rules for identifying document parts and creating nested element structures. These rules include:

  • An XML document can only have one document element. The document element is a single element that contains all the content considered to be part of the document itself. This document root element is the first element to appear after the document prolog. For more information, see Elements.
  • All XML elements must have end tags. While end tags may be optional with certain HTML elements, all elements in XML must have an end tag. For more information, see Elements.
  • XML elements cannot overlap. If the start tag for an element appears within another element, it must end within the same containing element. For example, the following HTML code suggests a combination of bold and italic by overlapping the structures.
    <b>This is bold text. <i>This is bold italic text.</b> This is italic text.</i>

    In some HTML browsers, this text appears as follows.

    This is bold text. This is bold italic text. This is italic text.

    In an XML parser, however, all processing halts as soon as </b> is encountered because the XML parser is looking for </i>, and will not accept </b>. To achieve the same formatting in XML, use the following syntax.

    <b>This is bold text.</b> <i><b>This is bold italic text.</b> This is italic text.</i>

    This extra work for XML document creators results in a leap forward for interoperability. Because XML processors have far less "guessing" code, they fit more easily into smaller-scale processing, like embedded systems. Structural ambiguities are eliminated from XML documents — all XML parsers see the same nested element structures.

  • All attribute values must be quoted, whether or not they contain spaces. You still have the option of single- or double-quotes. For more information, see Attributes.
  • You cannot use the characters <, >, or & within the text of your documents. Use the built-in entities &lt;, &gt;, or &amp;. For more information, see Character and Entity References.

XML Semantics

Although XML is unforgiving about syntax, it offers developers more options for defining meaning in XML documents. HTML is basically one vocabulary with a few variations; <b> always means the same thing to an HTML processor. With XML, you can create your own markup vocabulary or choose from markup vocabularies appropriate to your industry or project type. Schemas and document type definitions (DTDs) let you describe these vocabularies, but you can also create documents using vocabularies without formal definitions. Namespaces help you identify the vocabulary you are using.

This approach requires architectures different from those used by browsers. Developers cannot count on XML applications to understand what their markup means or how it is to be presented, understandings that were built into HTML browsers. Browsers can still present XML, but require a style sheet built using cascading style sheets (CSS) or XSL Transformations (XSLT), to format to your specifications. Some browsers, including Internet Explorer 5.0 and later, include a default style sheet, but it is designed more for diagnostics than for presenting information to end users.

XML applications can also bring their own logic to XML vocabularies, rather than relying on style sheets. This logic may take the form of simple scripts or binding to particular presentation modes, or it may involve writing an entire application from scratch. These applications can take advantage of their built-in knowledge of the labeled structures contained in XML documents to process the information in those documents, present them to users, connect them with other data sources, or redirect them to other appropriate consumers.


Advantages of the XML Format

In some ways, XML is just another data format. However, XML has several advantages over other formats when storing information.

  • XML allows developers to create their own labeled structures for storing information.
  • XML parsing is well-defined and widely implemented, making it possible to retrieve information from XML documents in a variety of environments.
  • XML is built on a Unicode foundation, making it easier to create internationalized documents.
  • Applications can rely on XML parsers to do some structural validation, as well as data type checking (when schemas are used).
  • XML formats are text-based, making them more readable, easier to document, and sometimes easier to debug.
  • Tools are available for XML processing on different platforms, making it simpler to use XML instead of binary formats to exchange complex information streams.
  • XML documents can use much of the infrastructure already built for HTML, including the HTTP protocol and some browsers.

XML isn't appropriate for every situation, however. XML documents tend to be more verbose than the binary formats they replace. They take up more network bandwidth and storage space, or require more processor time for compression. XML parsing can be slower than parsing highly optimized binary formats and can require more memory. However, careful application design can avoid some of these problems.


Creating a Simple XML Document

To demonstrate how XML structures can be used to break down and describe information, we will create a very basic XML document containing an employee record that includes the following fields.

  • Name
  • Home Address
  • Job Title
  • Salary

This is the sample employee record.

Shane S. Kim
1234 South Street
Anywhere, NY 10001
USA
Vice President of Finance
$175,000

Defining Basic Elements

To start our conversion to XML, we need a document or root element, in this case, <employeeRecord>, to hold all of our document content. For more information about the document or root element, see Elements.

Next, we will put the employee name into a <name> element; the address into a <homeAddress> element; the title into a <jobTitle element>; and the salary into a <salary> element.

<employeeRecord>
<name>Shane S. Kim</name>
<homeAddress>1234 South Street
Anywhere, NY 10001
USA</homeAddress>
<jobTitle>Vice President of Finance</jobTitle>
<salary>$175,000</salary>
</employeeRecord>

The beginnings of elements are marked with start tags, like <employeeRecord>, while the ends of elements are marked with end tags, like </employeeRecord>.

All of the elements nest properly. No element contains another element's start tag without including its end tag as well.

Refining Elements

The <name> and <homeAddress> elements contain information that might be useful for sorting and searching, for example, sorting the list by family name or finding all employees who live in a certain country or postal code.

We will add some child elements, <givenName>, <middleName>, and <familyName>, to the name element.

<name><givenName>Shane</givenName> <middleName>S.</middleName> <lastName>Kim</lastName></name>

We will also add more detail to our home address element.

<homeAddress><street>1234 South Street</street>
<city>Anywhere</city>, <stateProvince>NY</stateProvince> <postalCode>10001</postalCode>
<country>USA</country></homeAddress>

The document now looks as follows.

<employeeRecord>
<name><givenName>Shane</givenName> <middleName>S.</middleName> <lastName>Kim</lastName></name>
<homeAddress><street>1234 South Street</street>
<city>Anywhere</city>, <stateProvince>NY</stateProvince> <postalCode>10001</postalCode>
<country>USA</country></homeAddress>
<jobTitle>Vice President of Finance</jobTitle>
<salary>$175,000</salary>
</employeeRecord>

In this version, element structures identify all of the document content. If we had content that might not belong in the document or that might not ever need to contain further structure, we might use an attribute. For example, if this company were paying salaries in more than one currency, it might make sense to indicate that the salary presented here is in U.S., not Canadian, dollars. A currency attribute on the salary element lets us indicate that as follows.

<salary currency="USD">$175,000</salary>

In a similar way, an employeeID attribute on the <employeeRecord> element might make it easier to manipulate employee record documents, especially if we had to combine multiple records into a single XML document.

<employeeRecord employeeID="2344-12Z">

The complete document now looks as follows.

<employeeRecord employeeID="2344-12Z">
<name><givenName>Shane</givenName> <middleName>S.</middleName> <lastName>Kim</lastName></name>
<homeAddress><street>1234 South Street</street>
<city>Anywhere</city>, <stateProvince>NY</stateProvince> <postalCode>10001</postalCode>
<country>USA</country></homeAddress>
<jobTitle>Vice President of Finance</jobTitle>
<salary currency="USD">$175,000</salary>
</employeeRecord>


Displaying the File in Internet Explorer

Microsoft® Internet Explorer provides a default view of XML documents that displays their structure, in addition to support for styled display of XML information using cascading style sheets (CSS) or Extensible Stylesheet Language Transformations (XSLT). If an XML document contains an xml-stylesheet processing instruction, Internet Explorer uses the specified style sheet to present the information. If no xml-stylesheet processing instruction is present, Internet Explorer applies its default style sheet.

The default style sheet is useful for a number of common development cases. Loading a document into Internet Explorer causes the Microsoft XML Parser (MSXML) to parse the document and check whether it is a well-formed. If the parse fails, Internet Explorer reports error messages. If the parse succeeds, Internet Explorer presents the document structure as an outline, with small + and – icons for expanding and closing sections of the document. If you have long documents with many large sections, this view can help you quickly navigate the information.

Like other Web content, you can load XML documents into Internet Explorer through the Open command on the File menu, a hyperlinked URL, or from the file system.

See Also

Displaying XML Files in a Browser


XML Fundamentals

Information about XML document components is available in the following topics.

  • Document Map
  • Using XML with HTML
  • Using Namespaces in XML Documents


Document Map

The following is an XML document. Click on the colored text for more information about each structural construct.


Elements

Elements form the backbone of XML documents, creating structures you can manipulate with programs or style sheets. Elements identify named sections of information and are built using markup tags that identify the name, start, and end of the element.

Elements can also contain attribute names and values, which provide additional information about your content. For more information, see Attributes.

Element Names

All elements must have names. Element names are case-sensitive and must start with a letter or underscore. An element name can contain letters, digits, hyphens, underscores, and periods.

Note Colons are reserved for use with namespaces. For more information about which Unicode characters are acceptable letters and digits, see Appendix B of the XML specification.

Start Tags, End Tags, and Empty Tags

Tags establish boundaries around the content, if any, of the element.

Start tags indicate the beginning of an element and use the following general syntax.

<elementName att1Name="att1Value" att2Name="att2Value"...>

For elements that do not have attributes, the start tag can be reduced.

<elementName>

End tags indicate the end of an element and cannot contain attributes. End tags always take the following form.

</elementName>

An element is generally considered to include the start and end tags, and everything in between.

<person><givenName>Peter</givenName> <familyName>Kress</familyName></person>

In this case, the <person> element contains two other elements, <givenName> and <familyName>, along with a space that separates them. The <givenName> element contains the text 'Peter' while the <familyName> element contains the text 'Kress'.

Empty tags are used to indicate elements that have no textual content, though they may have attributes. The HTML img and br elements are examples of empty elements. Empty tags can be used as a shortcut when there is no content between the start and end tags of a document. Empty tags look like start tags, except that they contain a slash (/) before the closing >.

<elementName att1Name="att1Value" att2Name="att2Value".../>

In XML, you can indicate an empty element with start and end tags and no white space or content in between, for example, <giggle></giggle>, or you can use an empty tag, for example, <giggle/>. The two forms produce identical results in an XML parser.

Element Relationships

Relationships between elements are described using either family or tree metaphors. XML documents must contain a document element (also known as a root element). Although it can be preceded and followed by other markup, such as declarations, processing instructions, comments, and white space, the root must contain all of the content considered to be part of the document itself. For example, the following code can be an XML document with <person> as its root element.

<person><givenName>Stephanie</givenName> <familyName>Bourne</familyName></person>

The following fragment cannot be an XML document because it has multiple root elements.

<givenName>Stephanie</givenName>
<familyName>Bourne</familyName>
Note Document fragments can be useful as parts of an XML document but should not be passed to the parser on their own. The parser will report an error when it encounters the second element or text outside of an element.

In the tree metaphor, the leaves refer to elements that do not contain any other elements, like leaves on the end of a branch. Leaf elements are generally elements containing only text or nothing at all; leaf nodes are generally empty elements or text. In the document map, all of the text describing the books is stored in leaf elements; the text itself is the leaf node.

Family metaphors, such as parent, child, ancestor, descendant, and sibling, are used to describe relationships between elements relative to each other, not necessarily to the entire document. The following abstract sample document illustrates the relationships between elements.

<a>
 <b>
   <c>
    <d/><e/><f/>
   </c>
 </b>
</a>

The <a> element contains the <b> element, which contains the <c> element, which contains the <d>, <e>, and <f> elements. Using the tree metaphor, <a> is the root element, and <d>, <e>, and <f> are leaf elements. Although <b> and <c> might be considered trunks or branches, these descriptions are rarely used.

The family metaphors provide more levels of description. The only siblings in this document are the <d>, <e>, and <f> elements, all of which are contained by the <c> element. The <c> element is the parent of the <d>, <e>, and <f> elements; the <d>, <e>, and <f> elements are the child elements of the <c> element. In the same way, the <b> element is the parent of the <c> element and the <c> element is the child of the <b> element, while the <a> element is the parent of the <b> element and the <b> element is the child of the <a> element.

Ancestors and descendants are defined in a way similar to parents and children, except that they do not have to contain or be contained directly. The <a> element is the parent of the <b> element, and the ancestor of every element in the document. The <d>, <e>, and <f> elements are descendants of the <a>, <b>, and <c> elements.

See Also

Document Map

Other Resources Other Resources

Appendix B, Character Classes


Prolog

The prolog refers to the information that appears before the start tag of the document or root element. It includes information that applies to the document as a whole, such as character encoding, document structure, and style sheets.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="show_book.xsl"?>
<!DOCTYPE catalog SYSTEM "catalog.dtd">
<!--catalog last updated 2000-11-01-->

Processing instructions can also appear in the prolog, for example, the xml-stylesheet processing instruction, <?xml-stylesheet type="text/xsl" href="show_book.xsl"?>. For more information, see Processing Instructions.

Comments can appear in the prolog, for example, <! — catalog last updated 2000-11-01--!>. For more information, see Comments.


XML Declaration

The XML declaration must appear as the first line of the document without other content, including white space, in front of the start <.

The XML declaration in the document map consists of the following:

  • The version number, <?xml version="1.0"?>.

    This is mandatory. Although the number will change for future versions of XML, 1.0 is the current version.

  • The encoding declaration, <?xml version="1.0" encoding="UTF-8"?>

    This is optional. If used, the encoding declaration must appear immediately after the version information in the XML declaration, and must contain a value representing an existing character encoding.

An XML declaration may also contain a standalone declaration, for example, <?xml version="1.0" encoding="UTF-8"? standalone="yes"?>. Like the encoding declaration, the standalone declaration is optional. If used, the standalone declaration must appear last in the XML declaration.

Encoding Declaration

The encoding declaration identifies which encoding is used to represent the characters in the document. Although XML parsers can determine automatically if a document uses the UTF-8 or UTF-16 Unicode encoding, this declaration should be used in documents that support other encodings.

For example, the following is the encoding declaration for a document that uses the ISO-8859-1 (Latin 1).

<?xml version="1.0" encoding="ISO-8859-1"?>
Note Case in the value specified is not considered by the encoding declaration. "ISO-8859-1" is the equivalent of "iso-8859-1".

The following is the encoding declaration for a document that uses the Japanese encoding method Shift-JIS.

<?xml version="1.0" encoding="Shift-JIS"?>

For more information about how the Microsoft® XML Parser (MSXML) handles character encodings, see Character Encoding, XML, and MSXML.

Standalone Declaration

The standalone declaration indicates whether a document relies on information from an external source, such as external document type definition (DTD), for its content.

If the standalone declaration has a value of "yes", for example, <?xml version="1.0" standalone="yes"?>, the parser will report an error if the document references an external DTD or external entities.

Leaving out the standalone declaration produces the same result as including a standalone declaration of "no". The XML parser will accept external resources, if there are any, without reporting an error.

See Also

Document Map


Processing Instructions

Processing instructions can be used to pass information to applications in a way that escapes most XML rules. Processing instructions do not have to follow much internal syntax, may include markup characters without escaping them, and can appear anywhere in the document outside of other markup. They can appear in the prolog, including the document type definition (DTD), in textual content, or after the document. Their appearance is not noted by schema or DTD processors.

Processing instructions must begin with an identifier called a target, which follows rules similar to those for element and attribute names. Processing instruction targets are case-sensitive and must start with a letter or underscore. The rest of the target can contain letters, digits, hyphens, underscores, periods, and colons. Any valid XML textual characters can appear after the target.

Note The Worldwide Web Consortium Namespaces in XML recommendation suggests you avoid the use of colons in processing instruction names.

The following is the processing instruction syntax in the document map.

<?xml-stylesheet type="text/xsl" href="show_book.xsl"?>

Processing of the contents ends immediately after the string ?> is encountered.

Style Sheet Processing Instructions

In accordance with the W3C recommendation, Microsoft® Internet Explorer implements an xml-stylesheet processing instruction. This processing instruction must appear in the prolog, before the document or root element. Multiple processing instructions can appear, which can be useful with cascading style sheets, but most browsers use the first supported style sheet and ignore the rest.

The syntax for a style sheet processing instruction is:

<?xml-stylesheet type="type" href="uri" ?>

where

type is text/css (to link to a cascading style sheet file) or text/xsl (to link to an XSLT file)

uri is the Uniform Resource Identifier (URI) of the style sheet. This URI is relative to the location of the XML document itself.

The following is an xml-stylesheet processing instruction identifying a style sheet built using a cascading style sheet.

<?xml-stylesheet href="/style.css" type="text/css" title="default stylesheet"?>

The following is an xml-stylesheet processing instruction identifying a style sheet built using Extensible Stylesheet Language (XSL).

<?xml-stylesheet href="/style.xsl" type="text/xsl" title="default stylesheet"?>

The following processing instruction is legal, but difficult for applications to process.

<?style – oh, try /style.css ?>

Many processing instructions use pseudo-attributes, content that looks like attributes and is easier for applications to process. The preceding example can be rendered using the W3C xml-stylesheet processing instruction:

<?xml-stylesheet href="/style.css" type="text/css" title="default stylesheet"?>

You can use processing instructions in the prolog to specify other document-wide processing, but you must write an application to support them.

Note Although the use of processing instructions is sometimes discouraged, their loose structure and the flexibility of their placement make them useful for sending messages to an application without disrupting the flow of XML information.

See Also

Document Map

Other Resources Other Resources

Worldwide Web Consortium Namespaces in XML Recommendation | Associating Style Sheets with XML Documents, Version 1.0 (W3C Recommendation 29 June 1999)


DOCTYPE Declaration

The DOCTYPE declaration provides a space for a document to identify its root element and document type definition (DTD) by reference to an external file, through direct declarations, or both.

A DOCTYPE declaration can contain:

  • The name of the document or root element.

    This is required if the DOCTYPE declaration is used.

  • System and public identifiers for the DTD that can be used to validate the document structure.

    If a public identifier is used, a system identifier must also be present.

  • An internal subset of DTD declarations.

    The internal subset appears between square brackets ([ ]).

A DOCTYPE declaration is mandatory if the document is to be processed in a validating environment. To be valid, the DOCTYPE declaration must identify a DTD that corresponds to the document structure of the document. Nonvalidating parsers will accept documents without DOCTYPE declarations.

The simplest DOCTYPE declaration identifies only the root element of the document.

<!DOCTYPE rootElement>

More often, documents that use the DOCTYPE declaration reference an external document containing the declarations that make up the DTD. The following can be used to identify the external DTD.

<!DOCTYPE rootElement SYSTEM "URIreference">

The URIreference points to a file containing the declarations.

<!DOCTYPE rootElement PUBLIC "PublicIdentifier" "URIreference">

The PublicIdentifier provides a separate identifier that some XML parsers can use to reference the DTD in place of the URIreference. This is useful if the parser is used on a system without a network connection or where that connection would slow down processing significantly.

DOCTYPE declarations can also include declarations directly, in what is referred to as the internal subset. If a DOCTYPE declaration includes the entire DTD directly, without reference to external files, it uses the following syntax.

<!DOCTYPE rootElement [
declarations
]>

If the DOCTYPE declaration includes declarations that are to be combined with external files or the external subset, it uses the following syntax.

<!DOCTYPE rootElement SYSTEM "URIreference"[
declarations
]>

or

<!DOCTYPE rootElement PUBLIC "PublicIdentifier" "URIreference"[
declarations
]>


Comments

Content that is not intended for the XML parser, such as notes about document structure or editing, can be included in a comment. Comments begin with a <!-- and end with a -->, for example, <!--catalog last updated 2000-11-01-->.

Comments can appear in the document prolog, including the document type definition (DTD); after the document; or in the textual content. Comments cannot appear within attribute values. They cannot appear inside of tags.

The parser considers the comment finished when it encounters a -->; it then resumes processing the document as normal XML. For this reason, the string --> cannot appear inside of a comment. Apart from that restriction, any legal XML characters can appear in a comment, much like a CDATA section. This makes them very useful for removing XML comment from the stream seen by the parser without removing the content from the document.

The following comment can be used to strip out markup temporarily.

<!--- <test pattern="SECAM" /><test pattern="NTSC" />-->
Note In HTML, you can use comments to hide scripts and style sheets. To use this technique in XML, you may have to retrieve the comment, extract its contents, check for markup characters, and then reparse it. In this case, CDATA sections are a better option.


Textual Content

Because of its support for the Unicode character set, XML supports a range of characters, including letters, digits, punctuation, and symbols. Most control characters and Unicode compatibility characters are not allowed. For a complete list of character classes, see Appendix B of the XML specification.

Note Because XML relies on <, >, and & to delimit markup, you should represent these characters using the character and entity references described in the following topic or confine them to CDATA sections.

See Also

CDATA Sections | Character and Entity References

Other Resources Other Resources

Appendix B, Character Classes


Character and Entity References

Character and entity references provide ways to include information in XML documents by reference rather than by typing characters into the document directly. This can be useful in cases in which:

  • Characters cannot be entered directly into a document because they would be interpreted as markup.
  • Characters cannot be entered directly into a document because of input device limitations.
  • Characters cannot be transported reliably through a processor limited to one-byte characters.
  • A character string or document fragment appears repeatedly and can be abbreviated.

For content representation, XML provides a number of syntactical constructs that start with an ampersand (&) and end with a semi-colon (;).

Character references provide a way to insert Unicode characters that are identified by a number pointing to a Unicode code point. Code points can be identified using either decimal or hexadecimal notation.

&#value;
Syntax used for decimal references.
&#xvalue;
Syntax used for hexadecimal references.

For example, to insert the Euro symbol, a character still missing from many keyboards, you can insert &#x20AC; or &#8364; into a document.

The following table lists the five built-in entities for the characters used for XML markup.

Entity | Entity Reference | Meaning
lt | &lt; | < (less than)
gt | &gt; | > (greater than)
amp | &amp; | & (ampersand)
apos | &apos; | ' (apostrophe or single quote)
quot | &quot; | " (double quote)

In cases where the character might cause the XML parser to misinterpret the document structure, use the entity instead of typing the character. The &apos; and &quot; entity references are most commonly used in attribute values.

To write AT&T, for example, use AT&amp;T. For a<b, use a&lt;b. For b>c, use b&gt;c.

You can also define your own entities, much like HTML defines a set of entities for use in HTML. &apos is not recognized as an HTML file; $#.... must be used when transforming to HTML.

If you're working with a document type definition (DTD) that has defined entities, you can reference them in document content by using the following syntax.

&entityName;


Character Encoding, XML, and MSXML

Character encodings provide a map between a series of numbers and the characters people expect to see when they enter text into computers. The capital letter "A", for example, is represented by the decimal number 65 (41 in hexadecimal) in a variety of character encodings, including the ASCII text familiar to many Western programmers and Windows Code Page-1252, the default encoding used by most Microsoft® Windows® Western systems.

Character encodings are not fonts, which provide graphic representations, glyphs, that map to a particular character encoding. Microsoft Word, for example, includes a version of Arial (Arial Unicode MS) with tens of thousands of characters.

All XML processors are required to understand two transformations of the Unicode character encoding, UTF-8 and UTF-16. The Microsoft XML Parser (MSXML) supports more encodings, but all text in XML documents is treated internally as the Unicode UCS-2 character encoding.

Even different platforms representing the same set of Western characters can use different bytes to represent the same character, as shown in the following table.

Byte | Windows (CP1252) | Macintosh (MacRoman)
140 | Œ | å
229 | å | Â
231 | ç | Á
232 | è | Ë
233 | é | È

Parsers can read in documents written ISO-8859-1, Big-5, or Shift-JIS, but the processing rules treat everything as Unicode. MSXML and other XML parsers perform the conversion while loading XML documents.

There are some limitations to auto-detecting character encodings. For example, 8-bit ASCII text is acceptable UTF-8, but UTF-8 is more than 8-bit ASCII text. For reliable processing, XML documents that use character encodings other than UTF-8 or UTF-16 must include an encoding declaration in the XML declaration. This makes it possible for a parser to read the characters correctly or report errors when it cannot process an encoding.

Because the XML declaration is written in basic ASCII text, parsers can read its contents even if the document is in a very different encoding. The encoding declaration significantly increases the likelihood that documents in encodings other than UTF-8 and UTF-16 will be interpreted correctly.

Some transactions, for example, those carried over HTTP and e-mail protocols, also provide information about character encodings. Microsoft Internet Explorer uses that information in document processing, but it isn't available, for example, if you load an XML document from a local hard drive or even a file server.

XML Data Islands and Character Encodings

XML data islands inside of HTML documents receive different encoding handling, depending on whether the content is stored directly within the xml element or referenced by a src attribute.

XML data islands that contain the XML directly in the HTML document use the encoding of the surrounding HTML document. Because the entire document is assumed to use the same encoding, this approach significantly simplifies parsing.

XML data islands that reference the content through a src attribute are less constrained. The XML documents they reference can have an XML declaration containing a character encoding, and MSXML will use that character encoding. The contents of the data island will be presented as Unicode, but the parser will handle the conversion automatically.

See Also

XML Declaration


CDATA Sections

CDATA sections provide a way to tell the parser that there is no markup in the characters contained by the CDATA section. This makes it much easier to create documents containing sections where markup characters might appear, but where no markup is intended. CDATA sections are commonly used for scripting language content and sample XML and HTML content.

The CDATA section in the document map uses the following syntax.

<![CDATA[An in-depth look at creating applications with XML, using <, >,]]>

When an XML parser encounters the initial <![CDATA[, it reports the content that follows as characters without attempting to interpret them as element or entity markup. Character references do not work within CDATA sections. When it encounters the concluding ]]>, the parser stops reporting and returns to normal parsing.

For example, you can include either of the following CDATA sections in an XML document without causing the parser to report an error.

<![CDATA[</this is malformed!</malformed</malformed & worse>]]>

or

<![CDATA[if (c<10)]]>
Note Content within CDATA sections must be within the range of characters permitted for XML content; control characters and compatibility characters cannot be escaped this way. In addition, the sequence ]]> cannot appear within a CDATA section because this sequence signals the end of the section. This means that CDATA sections cannot be nested. The sequence also appears in some scripts. Within scripts, it is usually possible to substitute] ]> for ]]>.

See Also

Document Map


Attributes

Attributes allow you to add information about an element using name-value pairs. Attributes are often used to define properties of elements that are not considered the content of the element, though in some cases (for example, the HTML img element) the content of the element is determined by attribute values.

Attributes can appear in start or empty tags, but not in end tags. The syntax looks like:

<elementName att1Name="att1Value" att2Name="att2Value"...>

or:

<elementName att1Name="att1Value" att2Name="att2Value".../>

Attributes must have both a name and a value. No names without values are permitted. An element may not have two attributes with the same name. Because the order in which attributes appeared inside of an element is not considered important by XML, it may not be preserved by the XML parser.

Like element names, attribute names are case-sensitive and must start with a letter or underscore. The rest of the name may contain letters, digits, hyphens, underscores, and periods.

Note Colons are reserved for use with namespaces. For more information about which Unicode characters are acceptable letters and digits, see Appendix B of the XML specification.

Attribute values must follow the same rules as normal textual content, with a few additional restrictions. Attribute values can contain only text, not element markup. Entity references and character references are allowed within attribute values, but CDATA sections are not.

Finally, quotes may have to be escaped. The XML specification allows you to use either single or double quotes to indicate attributes, though the type of quote used must be the same on both sides of the attribute value. You must use quotes around attribute values, however. XML parsers will simply reject documents that do not use quotes around attribute values and report an error.

If you use single quotes to indicate an attribute value, you must represent single quotes inside the attribute value using the &apos; entity reference.

<myElement contraction='isn&apos;t' />

If you use double quotes to indicate an attribute value, you must represent double quotes inside the attribute value using the &quot; entity reference.

<myElement question="They asked &quot;Why?&quot;" />

You can, however, use double quotes inside of single-quoted attribute values and vice-versa, as the following examples demonstrate.

<myElement contraction="isn't" />
<myElement question='They asked "Why?"' />

You can also use different types of quotes on different attribute values within the same element.

<myElement contraction="isn't" question='They asked "Why?"' />

XML parsers do not preserve white space within attribute values the same way that they preserve white space within element textual content. In a validating parser with access to a DTD, all white space within an attribute value of any type other than CDATA is replaced with a single space; starting and ending white space will be stripped.

Other Resources Other Resources

Appendix B, Character Classes


White Space

The Worldwide Web Consortium (W3C) XML specification normalizes different line-ending conventions to a single convention but preserves all other white space, except in attribute values. XML also provides a set of tools that documents can use to signal to applications if white space must be preserved.

White Space and the XML Declaration

According to the current XML 1.0 standard, white space is not allowed before the XML declaration.

<?xml version="1.0"?>
 <BOOK>
  <BOOKNAME>XML</BOOKNAME>
 </BOOK>

If white space appears before the XML declaration, it will be treated as a processing instruction. The information, particularly the encoding, may not be used by the parser.

For more information about the XML declaration, see XML Declaration.

White Space in Element Content

XML parsers are required to report all white space that appears in element content within a document. For this reason, the following three documents are different to an XML parser.

<document>
<data>1</data>
<data>2</data>
<data>3</data>
</document>

and:

<document><data>1</data><data>2</data><data>3</data></document>

and:

<document><data>1</data> <data>2</data> <data>3</data></document>

For some applications, the values of the three data points matter more than the pretty-printing. For document-oriented XML applications, white space preservation can be critical.

Document authors can use the xml:space attribute to identify portions of documents where white space is considered important. Style sheets can also use the xml:space attribute as a hook to preserve white space in presentation. However, because many XML applications do not understand the xml:space attribute, its use is considered advisory.

The xml:space attribute accepts two values.

default
This value allows the application to handle white space as necessary. Not including an xml:space attribute produces the same result as using the default value.
preserve
This value instructs the application to maintain white space as is, suggesting that it might have meaning.

The values of xml:space attributes apply to all descendants of the element containing the attribute unless overridden by one of the child elements.

For example, the following documents specify the same white space behavior.

<poem xml:space="default">
<author>
<givenName>Alix</givenName>
<familyName>Krakowski</familyName>
</author>
<verse xml:space="preserve">
<line>Roses   are  red,</line>
<line>Violets  are  blue.</line>
<signature xml:space="default>-Alix</signature>
</verse>
</poem>

and:

<poem xml:space="default">
<author xml:space="default">
<givenName xml:space="default">Alix</givenName>
<familyName xml:space="default">Krakowski</familyName>
</author>
<verse xml:space="preserve">
<line xml:space="preserve">Roses   are  red,</line>
<line xml:space="preserve">Violets  are  blue.</line>
<signature xml:space="default>-Alix</signature>
</verse>
</poem>

In both examples, the application is notified that all of the white space in the lines of the poem must be preserved, but that white space in other parts of the document can be handled as necessary.

Like its language-indicating counterpart, xml:lang, the xml:space attribute must be declared in a document type definition (DTD) if used in a validating environment. The xml namespace does not need to be declared because it is reserved by the XML specification.

By default, the Microsoft XML Parser (MSXML) does not honor the xml:space attribute. If an application must honor the xml:space attribute, the preserveWhiteSpace property of the DOMDocument object must be set to True prior to parsing.

xmldoc= new ActiveXObject("Msxml2.DOMDocument");
xmldoc.preserveWhiteSpace = true;
xmldoc.load(url);

The MSXML parser also provides settings that let you delegate application white space handling to the parser. For more information, see White Space and the DOM.

Note Preserving white space information may significantly increase the size of Document Object Model (DOM) trees because of the overhead involved in preserving white space nodes between elements.

White Space in Attributes

Although XML processors preserve all white space in element content, they frequently normalize it in attribute values. Tabs, carriage returns, and spaces are reported as single spaces. In certain types of attributes, they trim white space that comes before or after the main body of the value and reduce white space within the value to single spaces. (If a DTD is available, this trimming will be performed on all attributes that are not of type CDATA.)

For example, an XML document might contain the following.

<whiteSpaceLoss note1="this is a note." note2="this
is
a
note.">

An XML parser reports both attribute values as "this is a note.", converting the line breaks to single spaces.

If there is a DTD for the document, attributes that are declared to be of types other than CDATA have spaces removed from the beginning and end of the attribute value; all white space clusters inside the value are replaced with single spaces. If there is no DTD, the parser assumes that all attributes are of type CDATA.

End of Line Handling

XML processors treat the character sequence Carriage Return-Line Feed (CRLF) like single CR or LF characters. All are reported as a single LF character. Applications can save documents using the appropriate line-ending convention.


Using XML with HTML

The following topics discuss ways to extend HTML and format and transform XML.

  • Transforming and Querying XML
  • Formatting XML Documents
  • Augmenting HTML
  • Parsers and Parser Types


Transforming and Querying XML

As XML becomes a standard way to exchange data on the Web, the need arises for mechanisms to query XML, sort, filter, and shape extracted data, and transform one XML grammar into another.

The XML Path Language (XPath) provides a simple and concise syntax for identifying nodes in an XML document, based on the node's type, name, content, and context in relation to other nodes in the tree.

XSL Transformations (XSLT) provides a grammar in which the results of XPath queries are associated with templates to describe the materialization of data in the XML source document as a new XML document. While this forms the basis for transforming data to display formats such as HTML, any XML grammar can be output, providing for sorting and filtering within a single XML grammar, or translating data from one schema to another.

The Worldwide Web Consortium (W3C) is considering a more powerful query language for XML.

See Also

XSLT Developer's Guide | Using XPath Expressions to Select Nodes


Formatting XML Documents

Although Microsoft® Internet Explorer 5.0 and later provides a default style sheet that is useful for exploring document structures, some applications must present the information stored in XML documents directly to the user, without relying on scripts or additional processing code. Internet Explorer 5.0 and later provides support for cascading style sheets (CSS), and the Microsoft XML Parser (MSXML) provides enhanced support for the Extensible Stylesheet Language (XSL).

XML and Cascading Style Sheets

Cascading style sheets allow developers to describe formatting that should be applied to document structures. Cascading style sheets let document designers make statements like "all paragraph elements should be formatted as separate blocks, with a 24 pixel indent on the first line" or "all price elements should be presented in bold green 12 point sans-serif type except price elements with a status attribute of sale, which should be presented in red."

Cascading style sheets is commonly described as an annotative style language, meaning that it adds formatting information to the document tree rather than changing the document itself. Its lists of formatting rules can be combined or overridden to provide multiple layers of formatting information appropriate to different document variations without requiring change to the document structure itself.

XML, XSL, and XSLT

XSL provides a set of tools for transforming documents from their original labeled document structure to a new structure that can be used for presentation. Typically, developers create transformations from an XML vocabulary to HTML, though a 'formatting object' vocabulary is under development at the Worldwide Web Consortium (W3C).

XSL is commonly described as a transformative style language. Instead of adding information to the original document structure, it creates a new document structure based on rules applied to the content of the original. The transformation language used by XSL, XSL Transformations (XSLT), allows developers to create sophisticated templates detailing how the original document's information should be presented in the new document, known as the result document.

See Also

Augmenting HTML


Augmenting HTML

Adding semantic information to HTML pages is not easy. Historically, various programs have attempted to deal with this problem by using nonstandard tricks, such as hiding data inside HTML comments. However, these comments are awkward and, unlike XML, are not exposed to the object model.

To solve this, the Worldwide Web Consortium (W3C) has defined a format for putting XML-based data (data islands) inside HTML pages. Extending HTML through the use of data islands will allow a wide range of applications to use HTML as the primary document or display format and also use XML embedded within these documents to hold data.

An HTML page can therefore include, among other things, specific data about the subject of the page. For example, if the page displayed an advertisement for an author's most recent novel, the page can also contain XML data concerning that book, such as its ISBN number, publisher, or suggested retail price. It is not important that this information be displayed, but it is important that this information be accessible and understandable as data.

See Also

XML Data Islands


Parsers and Parser Types

From a developer's point of view, XML parsers are the fundamental XML component, a bridge between XML documents, seen as a long chain of bytes, and applications that process that XML. Almost all XML applications are built on top of parsers.

The parser is responsible for handling XML syntax and, if desired, checking the contents of the document against constraints established in a document type definition (DTD) or schema; the application must understand how to process or display the information. The application is insulated from the details of the XML document, allowing document creators can take advantage of those details without worrying about the application. Document creators must still present correctly structured information to an application, but they can do so using generic tools instead of creating new interfaces for every different transaction.

There are two basic kinds of XML parsers defined in the XML 1.0 specification. The Microsoft® XML Parser (MSXML) can operate in either validating or nonvalidating mode.

nonvalidating parsers
Check document syntax and report all violations of well-formedness constraints. Nonvalidating parsers can also add information to the document based on declarations in the DTD. MSXML does read the DTD, including external resources, and acts on that information.
validating parsers
Perform the same functions as nonvalidating parsers, but also compare the structures of documents to rules in the DTD.

The needs of your application will determine whether you use validating or nonvalidating mode. If you're building a generic XML application that doesn't expect to see a particular set of document structures, a nonvalidating parser will allow you to work with documents that weren't built to be valid. By default, Microsoft Internet Explorer uses nonvalidating mode to accommodate the largest possible number of documents.

On the other hand, if you're creating systems for exchanging information with other organizations, and have had to agree on the format and content of those exchanges, DTDs (or schemas) and validating parsers are a good choice. They provide an extra layer of processing that lets you trim a lot of structure-checking code from your programs, while ensuring that document structures conform to the formats you agreed on prior to the transaction.

In many ways, DTDs and schemas are like contracts, and validating parsers enforce the terms of those contracts.

Testing for well-formedness with Internet Explorer 5.5

You can open any XML document labeled as XML in Internet Explorer. If the document is well-formed, Internet Explorer will display the document according to the style sheet specified within the document. If the document does not specify a style sheet, Internet Explorer will display the document using its default style sheet for XML. If the document is not well-formed, Internet Explorer will report an error. If a document has multiple errors, you may have to fix an error, reopen the document, and fix the next error.

Note To label a document as XML, assign it a file extension of .xml if you are opening it from a local file system or file server, or a Multipurpose Internet Mail Extensions (MIME) type of 'text/xml' or 'application/xml' if you are opening it over a Web connection.

Testing for validity with Internet Explorer 5.5

To use Internet Explorer to validate an XML document, you must set a switch in the parser before loading the document.

Microsoft offers an XML validator that sets these switches and provides an interface. This validator allows you to enter an XML document either as a URL or through a form. The validator parses the document using the MSXML parser in validating mode and reports any errors.

The core of the validator is this snippet of Microsoft JScript® code.

xmldoc= new ActiveXObject("msxml2.DOMDocument");
xmldoc.validateOnParse = true;
xmldoc.load(url);

The code appears as follows in Microsoft Visual Basic® Scripting Edition (VBScript).

Set xmldoc = CreateObject("msxml2.DOMDocument")
xmldoc.validateOnParse = true
xmldoc.load(url)

Other Resources Other Resources

XML Validator


Using Namespaces in Documents

The Microsoft® XML Parser (MSXML) supports the World Wide Web Consortium (W3C) Namespaces in XML Recommendation specification. By using XML namespaces to qualify element names, you can avoid naming conflicts for elements that have the same name. Associating a Uniform Resource Identifier (URI) with a namespace ensures that only elements with the same name remain unambiguous.

Namespace support is integrated into the MSXML parser, including the Document Object Model (DOM), Extensible Stylesheet Language (XSL), XML Data Reduced (XDR) schemas, and XML schemas (XSD).

The following topics provide more information about namespaces and describe the namespace support features in MSXML.

  • Reasons for Namespaces
  • Namespace Prefixes
  • Declaring Namespaces
  • Namespace Scope

Other Resources Other Resources

W3C Namespaces in XML Recommendation


Reasons for Namespaces

The appeal of XML lies in the ability to invent tags that convey meaningful information that can be processed by applications and read by users. Namespaces allow you to associate a vocabulary (or namespace) with an element or attribute name.

Example

The following XML represents information about a book.

<BOOK>
 <TITLE>XML Developer's Guide</TITLE>
 <PRICE currency="US Dollar">44.95</PRICE>
</BOOK>

The following XML represents information about an author.

<AUTHOR>
 <TITLE>Ms</TITLE>
 <NAME>Ambercrombie Kim</NAME>
</AUTHOR>

Although the user can distinguish between the different interpretations of the <TITLE> element, a computer program, such as an XML parser, cannot differentiate between the two meanings. Without additional information, the parser cannot determine that the first <TITLE> element is intended to refer to a string representing the title of the book, and that the second refers to an enumeration representing the title of the author ("Mr. " , "Ms. " , "Mrs. " , and so on).

Example

The following examples shows TITLE associated with BookInfo and AuthorInfo namespaces.

<BookInfo:TITLE xmlns:BookInfo="books-namespace-URI">XML Developer's Guide</BookInfo:TITLE>
<AuthorInfo:TITLE xmlns:AuthorInfo="authors-namespace-URI">Ms.</AuthorInfo:TITLE>

The W3C Namespaces in XML recommendation provides the xmlns attribute to uniquely define a namespace for an XML document to use.

Example

The following examples show how to declare a namespace with the xmlns attribute.

xmlns=http://www.example.com/books.dtd
xmlns="urn:schemas-microsoft-com:xml-data


Namespace Prefixes

The name preceding the colon, the prefix, maps to an XML namespace identified by a Universal Resource Identifier (URI). The namespace ensures global uniqueness when merging XML sources, while the associated prefix — a short name that substitutes for the namespace's URI — must be unique only in the tightly scoped context of the document. With this scheme, no conflicts exist between tags and attributes, and two tags can be the same only if they are from the same namespace and have the same tag name. This allows a document to contain both book and author information without confusion about whether the <TITLE> element refers to the book or the author. If a computer program wanted to display the name of a book in a user interface, it would use the object model to look for the <TITLE> element of the BookInfo namespace.

Example

The following examples show the tiger element prefixed with zoo. This indicates that the animal element belongs to the zoo namespace as defined in the root element by the xmlns attribute.

<zoo: tiger>

Other Resources Other Resources

W3C Namespaces in XML Recommendation


Declaring Namespaces

The Microsoft® XML Parser (MSXML) provides support for associating elements and attributes with namespaces. You can use a default or explicit declaration to declare namespaces. In both cases, the declaration associates a Uniform Resource Identifier (URI) with particular element and attribute names.

Choosing Namespace URIs

Developers creating new XML vocabularies may need to choose URIs for use as namespace identifiers. The following are general guidelines for creating new vocabularies that need namespace identifiers.

  • Use namespace URIs that you control.

    Although the Namespaces in XML recommendation does not prohibit borrowing, do not create a new namespace using a URI you do not control.

  • Use URIs that are persistent.

    Although they are usually maintained, domain names do expire. Other URI facilities, such as Uniform Resource Names (URNs) and Permanent URLs (PURLs), guarantee persistence beyond the domain name infrastructure.

  • Use URIs that consistently point to the same location.

    Although the Namespaces in XML recommendation does not prohibit the use of relative URI references in namespace identifiers, their use is largely undefined.

  • Identify and describe the namespace URI in the documentation for your vocabulary.

Default Declaration

The default declaration declares a namespace for all elements contained by the element where the declaration appears. The following example declares the <catalog> element and all unprefixed elements and attributes within it to be members of the namespace "http://www.example.com/catalog/". The xmlns attribute is an XML keyword and is understood by namespace-aware XML parsers, including MSXML, to be a namespace declaration.

<catalog xmlns="http://www.example.com/catalog/">
  <book id="bk101">
     ...
  </book>
  <book id="bk109">
     ...
  </book>
</catalog>

Default declarations are commonly used when a document contains only elements from a particular namespace or when one namespace effectively dominates all others.

Explicit Declaration

An explicit declaration defines a shorthand, or prefix, to substitute for the full name of a namespace. Use an explicit declaration to reference a node from a namespace separate from your default namespace.

If the catalog example created in the document map had to represent its currency values using an element from a different namespace, it might include both a declaration for the catalog as a whole and an explicit declaration for the element describing the prices.

Explicit declarations of namespace prefixes use attribute names beginning with the xmlns attribute and followed by the prefix. The value of the attribute is the namespace URI.

Example

The following example declares "cat" and "money" to be shorthand for the full names of their respective namespaces. All elements beginning with cat: or money: are considered to be from the namespace "http://www.example.com/catalog/" or "http://www.example.com/currency/", respectively.

<cat:catalog xmlns:cat="http://www.example.com/catalog/"
   xmlns:money="http://www.example.com/currency/">
  <cat:book id="bk101">
     <cat:author>&#71;ambardella, Matthew</cat:author>
     <cat:title>XML Developer's &#x47;uide</cat:title>
     <cat:genre>Computer</cat:genre>
     <money:price>44.95</money:price>
     <cat:publish_date>2000-10-01</cat:publish_date>
     <cat:description><![CDATA[An in-depth look at creating applications with XML, using <, >,]]> and &amp;.</cat:description>
  </cat:book>
  <cat:book id="bk109">
     <cat:author>Kress, Peter</cat:author>
     <cat:title>Paradox Lost</cat:title>
     <cat:genre>Science Fiction</cat:genre>
     <money:price>6.95</money:price>
     <cat:publish_date>2000-11-02</cat:publish_date>
     <cat:description>After an inadvertant trip through a Heisenberg Uncertainty Device, James Salway discovers the problems of being quantum.</cat:description>
  </cat:book>
</cat:catalog>

Explicit declarations are useful when a node contains elements from different namespaces. You can also fix default namespace declarations with explicit namespace declarations.

Example

The following example is almost identical to the preceding example. However, all of the elements except price use the default namespace declaration, avoiding repeated cat: prefixes. All of the elements except price are associated with the namespace URI "http://www.example.com/catalog/"; price is associated with "http://www.example.com/currency/".

<catalog xmlns="http://www.example.com/catalog/"
   xmlns:money="http://www.example.com/currency/">
  <book id="bk101">
     <author>&#71;ambardella, Matthew</author>
     <title>XML Developer's &#x47;uide</title>
     <genre>Computer</genre>
     <money:price>44.95</money:price>
     <publish_date>2000-10-01</publish_date>
     <description><![CDATA[An in-depth look at creating applications with XML, using <, >,]]> and &amp;.</description>
  </book>
  <book id="bk109">
     <author>Kress, Peter</author>
     <title>Paradox Lost</title>
     <genre>Science Fiction</genre>
     <money:price>6.95</money:price>
     <publish_date>2000-11-02</publish_date>
     <description>After an inadvertant trip through a Heisenberg Uncertainty Device, James Salway discovers the problems of being quantum.</description>
  </book>
</catalog>

See Also

Document Map


Namespace Scope

Namespace declarations are scoped using an element container. All namespace prefixes are valid only within the element in which they are defined. Unqualified elements (those without an explicit namespace on the element) use the default namespace.

Example

The following example shows unqualified elements, <book id="bk101"> and <book id="bk109"> within the "http://www.example.com/catalog/" namespace.

<catalog xmlns="http://www.example.com/catalog/">
  <book id="bk101">
     ...
  </book>
  <book id="bk109">
     ...
  </book>
</catalog>

Example

In the following example, all unqualified elements within the <table> element are scoped to the default namespace "http://www.w3.org/TR/REC-html40". Within the <details> tag, the default namespace is set to "urn:beerstuff.org:brandinfo". All unqualified tags within the <details> element are scoped to this namespace.

<Beers>
 <!-- the default namespace is now that of HTML -->
 <table xmlns="http://www.w3.org/TR/REC-html40">
  <tr><td>Name</td><td>Origin</td><td>Description</td></tr>
  <tr>
   <!-- drop the HTML namespace inside table cells -->
   <td><brandName xmlns="urn:beerstuff.org:brandinfo">Huntsman</brandName></td>
   <td><origin xmlns="urn:beerstuff.org:brandinfo">Bath, UK</origin></td>
   <td>
    <details xmlns="urn:beerstuff.org:brandinfo">
     <class>Bitter</class>
     <hop>Fuggles</hop>
     <pro>Wonderful hop, light alcohol, good summer beer</pro>
     <con>Fragile; excessive variance pub to pub</con>
    </details>
   </td>
  </tr>
 </table>
</Beers>

The following table shows the elements and attributes of the preceding XML example and their properties as presented by the Microsoft® XML Parser (MSXML).

Node type | nodeName | namespaceURI | prefix | baseName
Element | Beers | n/a | n/a | Beers
Element | table | http://www.w3.org/TR/REC-html40 | n/a | table
Attribute | xmlns | n/a | xmlns | n/a
Element | tr | http://www.w3.org/TR/REC-html40 | n/a | tr
Element | td | http://www.w3.org/TR/REC-html40 | n/a | td
Element | td | http://www.w3.org/TR/REC-html40 | n/a | td
Element | td | http://www.w3.org/TR/REC-html40 | n/a | td
Element | tr | http://www.w3.org/TR/REC-html40 | n/a | tr
Element | td | http://www.w3.org/TR/REC-html40 | n/a | td
Element | brandName | urn:beerstuff.org:brandinfo | n/a | brandName
Attribute | xmlns | n/a | n/a | xmlns
Element | td | http://www.w3.org/TR/REC-html40 | n/a | td
Element | origin | urn:beerstuff.org:brandinfo | n/a | origin
Attribute | xmlns | n/a | xmlns |
Element | td | http://www.w3.org/TR/REC-html40 | n/a | td
Element | details | urn:beerstuff.org:brandinfo | n/a | details
Attribute | xmlns | n/a | xmlns |
Element | class | urn:beerstuff.org:brandinfo | n/a | class
Element | hop | urn:beerstuff.org:brandinfo | n/a | hop
Element | pro | urn:beerstuff.org:brandinfo | n/a | pro
Element | con | urn:beerstuff.org:brandinfo | n/a | con


XML DOM User Guide

The XML Document Object Model (DOM) provides a standardized way to access and manipulate the information stored in XML documents. The DOM application programming interface (API) serves as a bridge between applications and XML documents.

The Microsoft® XML Parser (MSXML) reads an XML document and parses its contents into a set of abstract information containers called nodes. These nodes represent the structure and content of the document, allowing applications to read and manipulate the information in the document without explicitly understanding XML syntax. After a document is parsed, its nodes can be explored in any direction; they are not limited to straight-through text file processing.

For more information about the Document Object Model, see Introduction to the DOM.

For script developers, the most important programming object is DOMDocument. The DOMDocument object exposes properties and methods that allow you to navigate, query, and modify the content and structure of an XML document. Each of the following objects exposes methods and properties that enable you to gather information about the instance of the object, manipulate the value and structure of the object, and navigate to other objects within the tree.

For developers using C, C++, or Microsoft Visual Basic®, these objects are exposed as the following COM interfaces.

  • IXMLDOMDocument/DOMDocument
  • IXMLDOMNode
  • IXMLDOMNodeList
  • IXMLDOMNamedNodeMap
  • IXMLDOMParseError

Reference Documentation

For complete reference material about each object, and the methods and properties exposed by that object, see XML DOM Objects/Interfaces.

For more information about integrating MSXML 4.0 with existing environments using MSXML, see Installing and Registering the MSXML 4.0 Technology Preview and GUID and ProgID Information.

The following topics explain how to use the XML DOM objects and collections. They discuss the methods and properties exposed by each object, and also address DOM persistence.

  • Using DOMDocument
  • Using IXMLDOMNode
  • Using IXMLDOMNodeList
  • Using IXMLDOMNamedNodeMap
  • XML DOM Persistence
  • Character Encoding, XML, and MSXML


Introduction to the DOM

The Document Object Model (DOM) presents an easily processed standardized interpretation of an XML document to applications and scripts. The DOM implementation in the Microsoft® XML Parser (MSXML) allows you to load or create a document; gather errors, if any; access and manipulate the information and structures contained within the document; and save the document back out to an XML file, if necessary.

DOM and MSXML

The DOM implementation is just one part of the MSXML parser. The following diagram shows the tasks involved in parsing an XML document and presenting the information to an application or script.

For another approach to XML document parsing, the MSXML parser also provides a different application programming interface, Simple API for XML (SAX2).

The DOM approach creates an object tree that is managed by the MSXML parser. This allows developers to take advantage of the logic built into MSXML for managing XML content, rather than having to create their own. Developers who need to build applications for specific purposes may find it more efficient to use SAX2 to read the document and then manage the information in their internal data structures.

For more information about SAX2, see the SAX2 Developer's Guide.

Modeling Documents as Node Trees

The DOM provides you with an interface for loading, accessing, manipulating, and serializing XML documents. The DOM provides a representation of a complete XML document stored in memory, providing random access to the contents of the entire document. The DOM allows applications to rely on the logic provided by the MSXML parser to handle XML-based information, using its facilities rather than writing custom code to read and process XML.

When the MSXML parser loads an XML document into a DOM, it reads it from start to finish and creates a logical model of nodes from the structures and content within the XML document. The document itself is considered a single node that contains all of the other nodes, including a node representing the root element, which, in turn, contains all of the element, attribute, and text nodes in the document. The following XML document has a simple multi-tier structure.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="show_book.xsl"?>
<!DOCTYPE catalog SYSTEM "catalog.dtd">
<!--catalog last updated 2000-11-01-->
<catalog xmlns="">
  <book id="bk101">
     <author>&#71;ambardella, Matthew</author>
     <title>XML Developer's &#x47;uide</title>
     <genre>Computer</genre>
     <price>44.95</price>
     <publish_date>2000-10-01</publish_date>
     <description><![CDATA[An in-depth look at creating applications with XML, using <, >,]]> and &amp;.</description>
  </book>
  <book id="bk109">
     <author>Kress, Peter</author>
     <title>Paradox Lost</title>
     <genre>Science Fiction</genre>
     <price>6.95</price>
     <publish_date>2000-11-02</publish_date>
     <description>After an inadvertant trip through a Heisenberg Uncertainty Device, James Salway discovers the problems of being quantum.</description>
  </book>
</catalog>

After MSXML parsing, the top two levels of the node structure representing this document will look like this.

The topmost node is the document itself, which contains all of the other nodes. Immediately within the document are nodes representing the XML declaration, the style sheet processing instruction, the DOCTYPE declaration, and the root element for the document, in this case, catalog.

The catalog element contains the real content of the document, and its structure is shown below.

This part of the DOM contains element, attribute, text, and CDATA nodes. (The character references and built-in entities are converted to ordinary text by the parser, but the CDATA section has its own node.)

Working with the DOM

The DOM allows applications to work with XML document structures and information as program structures rather than text streams. Applications and scripts can read and manipulate these structures without knowing the details of XML syntax, taking advantage of the facilities built into the DOM API of MSXML.

The DOM uses two key abstractions: a tree-like hierarchy and nodes that represent document content and structures. The hierarchy is composed of these nodes, which may contain or be contained by other nodes. For developers, this means that much of the work of XML processing requires navigating this tree structure to find or modify the information it contains. Working with XML requires thinking of information in terms of nested containers, and making sure that information is put into or retrieved from the right container.

The DOM treats nodes as generic objects, making it possible to create a script that loads a document and then traverses all of the nodes, reporting what it finds in the tree.

The following are exposed by the XML DOM.

  • DOMDocument
  • IXMLDOMNode
  • 8IXMLDOMNodeList
  • IXMLDOMNamedNodeMap

The DOM programming interfaces enable applications to traverse the tree and manipulate its nodes. Each node is defined as a specific node type, according to the XML DOM enumerated constants, which also define valid parent and child nodes for each node type. For most XML documents, the most common node types are element, attribute, and text. Attributes occupy a special place in the model because they are not considered child nodes of a parent, and are treated more like properties of elements. An additional programming interface, the IXMLDOMNamedNodeMap, is provided for attributes.

This sample Active Server Pages (ASP) script uses the MSXML parser to parse a document into a DOM tree, then move down the tree from the root node and report the kinds of nodes it encounters and their content.

The first version uses Microsoft Visual Basic® Scripting Edition (VBScript) to load the document and walk the tree. If no form input is provided, it presents the user with a form to gather the URL of an XML document. The user then submits that back to the script, which parses the document and presents a tree.

<%@LANGUAGE=VBScript%>
<html>
<head>
<title>Tree walk test - VBScript</title>
</head><body>
<%

function attribute_walk(node)

  For i=1 to indent
    Response.Write("&nbsp;")
  Next
  For Each attrib In node.attributes
   Response.Write("|--")
   Response.Write(attrib.nodeTypeString)
   Response.Write(":")
   Response.Write(attrib.name)
   Response.Write("--")
   Response.Write(attrib.nodeValue)
   Response.Write("<br />")
  Next
end function

function tree_walk(node)
dim nodeName

indent=indent+2

For Each child In node.childNodes
  For i=1 to indent
    Response.Write("&nbsp;")
  Next
  Response.Write("|--")
  Response.Write(child.nodeTypeString)
  Response.Write("--")
  If child.nodeType<3 Then
    Response.Write(child.nodeName)
    Response.Write("<br />")
  End If
  If (child.nodeType=1) Then
    If (child.attributes.length>0) Then
      indent=indent+2
      attribute_walk(child)
      indent=indent-2
    End If
  End If
  If (child.hasChildNodes) Then
    tree_walk(child)
  Else
    Response.Write child.text
    Response.Write("<br />")
  End If
Next

  indent=indent-2

end function

xmlFile=Request.Form("fileURI")

Dim root
Dim xmlDoc
Dim child
Dim indent

indent=0

Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.async = False
xmlDoc.validateOnParse=False
xmlDoc.load(xmlFile)
If xmlDoc.parseError.errorcode = 0 Then
'Walk from the root to each of its child nodes:
  Response.Write("<pre>")
  tree_walk(xmlDoc)
  Response.Write("</pre>")
Else
%>
<h1>XML Parsing - DOM Tree Walk Demo</h1>
<form id="location" method="post" action="">
<input type="text" name="fileURI" maxlength="255" size="20" id="XMLurl" />
<br />
<input type="submit" name="submit" value="submit" />
</form>
<% End If%>
</body></html>

At the bottom, the script contains a main routine that either loads a document and passes it to the tree walker or presents a form asking which document to load. This script relies on the tree_walk function, a recursive function that moves from node to node in the tree and presents a suitably formatted version of the contents. That function in turn relies on an attribute_walk function to present attribute content, because attribute nodes are not considered children of element nodes within the DOM.

The Microsoft JScript® version is similar; however, it requires extra lines of code to avoid overwriting variables during the recursive tree walking.

<%@LANGUAGE=JScript%>
<html>
<head>
<title>Tree walk test - JScript</title>
</head><body>
<%

function attribute_walk(node) {

  for (k=1; k<indent; k++) {
    Response.Write("&nbsp;");
  }
  for  (m=0; m<node.attributes.length; m++){
   attrib = node.attributes.item(m);
   Response.Write("|--");
   Response.Write(attrib.nodeTypeString);
   Response.Write(":");
   Response.Write(attrib.name);
   Response.Write("--");
   Response.Write(attrib.nodeValue);
   Response.Write("<br />");
  }
} //end attribute_walk

function tree_walk(node) {

indent=indent+2;
for (current=0; current<node.childNodes.length; current++) {
  child=node.childNodes.item(current);
  for (j=1; j<indent; j++){
    Response.Write("&nbsp;");
  }
  Response.Write("|--");
  Response.Write(child.nodeTypeString);
  Response.Write("--");
  if (child.nodeType<3) {
    Response.Write(child.nodeName);
    Response.Write("<br />");
  }
  if (child.nodeType==1) {
    if (child.attributes.length>0) {
      indent=indent+2;
      attribute_walk(child);
      indent=indent-2;
    }
  }
  if (child.hasChildNodes) {
//store information so recursion is possible
    depthList[depth]=current;
    depth=depth+1;
    tree_walk(child);
//return from recursion
    depth=depth-1;
    current=depthList[depth];

  }else{
    Response.Write (child.text);
    Response.Write("<br />");
  }
}

  indent=indent-2;

}

//recursion-tracking variables
depth=0;
depthList=new Array();

indent=0;
xmlFile=new String();

xmlFile=Request.Form("fileURI");
xmlFile=""+xmlFile; //makes string clean for passing to MSXML

xmlPresented=false;

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.validateOnParse=false;
//xmlFile="http://127.0.0.1/ms/local.xml"
if ((xmlFile)) {
 xmlDoc.load(xmlFile);
 if (xmlDoc.parseError.errorcode == null) {
  Response.Write("<pre>");
  tree_walk(xmlDoc);
  Response.Write("</pre>");
  xmlPresented==true;
 }
}
if (xmlPresented==false){
%>
<h1>XML Parsing - DOM Tree Walk Demo</h1>
<form id="location" method="post" action="">
<input type="text" name="fileURI" maxlength="255" size="20" id="fileURI" />
<br />
<input type="submit" name="submit" value="submit" />
</form>
<% } %>
</body></html>

Additional MSXML Features

The World Wide Web Consortium (W3C) Document Object Model Level 1 Specification defines two groups of DOM programming interfaces.

Fundamental
The W3C fundamental interfaces include those required to write applications that manipulate XML documents.
Extended
The W3C extended interfaces include those that make programming more convenient for developers.

The MSXML DOM implements both fundamental and extended interfaces and also provides additional methods to support XSL Transformations (XSLT), XPath, namespaces, and data types. This approach allows developers to work with a single consistent API for document processing and transformations.

For example, the selectNodes method supports XPath syntax to enable sophisticated queries for nodes within a particular context or subtree of the overall tree structure. The transformNode method supports the use of XSLT to perform transformations.

See Also

IXMLDOMNamedNodeMap | selectNodes Method | transformNode Method | XML DOM Enumerated Constants | Template-Driven Transformations | Using XPath Expressions to Select Nodes | Using Namespaces in Documents


Working with XML Document Parts

The Document Object Model (DOM) provides a generic container, the node, that can be used to represent elements, attributes, textual content, comments, processing instructions, entities, CDATA sections, and document fragments. Because each node type has different access methods and content limitations, it is sometimes easier to work with nodes belonging to a particular type. This section provides information about how to work with the following types of nodes.

  • Document
  • Elements
  • Attributes
  • Text Nodes
  • CDATA Sections
  • Processing Instructions
  • Comments
  • Entity
  • Entity References
  • Document Fragments
  • Document Type
  • Namespaces

Document

The document map is represented by the DOMDocument object, which contains all of the information about the document. The DOMDocument object acts as the root node for all of the other nodes in the DOM tree. It contains the root element of the document, as well as information from before the root element — the prolog — and after the end of the root element.

The DOMDocument node can contain multiple IXMLDOMProcessingInstruction and IXMLDOMComment nodes, and one each of the IXMLDOMElement and IXMLDOMDocumentType nodes. These nodes are treated as children, and will appear in the same sequence in which they appeared in the original XML document.

To create a new document object, you must create a new instance of Msxml2.DOMDocument. The following code is in Microsoft® JScript®.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");

The following code is in Microsoft Visual Basic® Scripting Edition (VBScript).

Set xmlDoc = CreateObject("Msxml2.DOMDocument")

After you create the DOMDocument object, you can set flags on it for different kinds of parsing and processing behavior, load XML documents, create new nodes inside the document to build an XML document from within your program, or persist your DOMDocument object as an XML file.

For more information about properties and methods of DOMDocument objects, see IXMLDOMDocument/DOMDocument.

Elements

Elements within an XML document are represented by IXMLDOMElement objects. Just as elements can contain elements, text, comments, processing instructions, CDATA sections, and entity references within XML documents, these objects can contain IXMLDOMElement, IXMLDOMText, IXMLDOMComment, IXMLDOMProcessingInstruction, IXMLDOMCDATASection, and IXMLDOMEntityReference objects.

Elements do not store attributes directly as children, however. Attributes can be retrieved or modified by name using the getAttribute and setAttribute methods, or manipulated as an IXMLDOMNamedNodeMap through the attributes property.

Creating an element requires that you already have created a DOMDocument object, as the createElement method belongs to DOMDocument. Although you can create and manipulate elements without adding them to the node list of DOMDocument, these elements will disappear as soon as the program completes and will not be persisted in XML documents. Generally, you'll want to assign elements a place in the document tree shortly after creation.

The following JScript code creates a DOMDocument object, and then uses that DOMDocument object to create an IXMLDOMElement object, which is then appended to the DOMDocument to be the root element of the document.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var rootElement=xmlDoc.createElement("memo");
xmlDoc.appendChild(rootElement);

The following code is in VBScript.

Set xmlDoc = CreateObject("Msxml2.DOMDocument")
Set rootElement=xmlDoc.createElement("memo")
xmlDoc.appendChild(rootElement)

For more information about properties and methods of IXMLDOMElement, see IXMLDOMElement.

Attributes

Although attributes belong to a particular element, they are not considered child nodes of element nodes. Instead, they behave more like properties of IXMLDOMElement.

Most of the methods for working with attributes come from IXMLDOMElement. Attributes can be manipulated in the following ways.

  • directly through the getAttribute and setAttribute methods of IXMLDOMElement.
  • as named IXMLDOMAttribute nodes with getAttributeNode and setAttributeNode.
  • as a set of nodes accessible through the attributes property and returned as an IXMLNamedNodeMap.

The following JScript example creates a new document containing a <memo> element, and then creates an attribute named author with a value of Pat Coleman.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var rootElement=xmlDoc.createElement("memo");
rootElement.setAttribute("author", "Pat Coleman");
xmlDoc.appendChild(rootElement);

The following code is in VBScript.

Set xmlDoc = CreateObject("Msxml2.DOMDocument")
Set rootElement=xmlDoc.createElement("memo")
rootElement.setAttribute("author", "Pat Coleman")
xmlDoc.appendChild(rootElement)

If you prefer to work with attribute nodes, you can create the attribute, and then create a text node to store its value. Attribute nodes can only contain text nodes and entity reference nodes. (If you need to create an attribute containing an entity reference, you must use this approach.)

Working with attribute nodes requires using the DOMDocument object to create attribute and text (and entity reference, if necessary) nodes before assigning the nodes to the element. The following JScript code uses this approach to perform the same work as the preceding examples, creating a <memo> element with an author attribute holding the value Pat Coleman.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var rootElement=xmlDoc.createElement("memo");
var memoAttribute=xmlDoc.createAttribute("author");
var memoAttributeText=xmlDoc.createTextNode("Pat Coleman");
memoAttribute.appendChild(memoAttributeText);
rootElement.setAttributeNode(memoAttribute);
xmlDoc.appendChild(rootElement);

The following code is in VBScript.

Set xmlDoc = CreateObject("Msxml2.DOMDocument")
Set rootElement=xmlDoc.createElement("memo")
Set memoAttribute=xmlDoc.createAttribute("author")
Set memoAttributeText=xmlDoc.createTextNode("Pat Coleman")
memoAttribute.appendChild(memoAttributeText)
rootElement.setAttributeNode(memoAttribute)
xmlDoc.appendChild(rootElement)

Developers who want to work with attributes as a set can also use the IXMLDOMNamedNodeMap collection returned by the attribute property of IXMLDOMElement.

For more information about properties and methods of IXMLDOMAttribute, see IXMLDOMAttribute.

Text Nodes

Text nodes store the character sequences that make up the content of XML elements and attributes. Text nodes cannot have child nodes because they represent content, not structure. Text nodes must be contained by element, attribute, document fragment, or entity reference nodes — they cannot be contained by the top-level document node, though the DOMDocument object is used to create text nodes. For more information, see Textual Content.

The createTextNode method of DOMDocument object is used to create new text nodes, instances of XMLDOMText. In the following JScript example, createTextNode is called twice — once to create a text node for an attribute value, and once to create a text node for element content.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var rootElement=xmlDoc.createElement("memo");
var memoAttribute=xmlDoc.createAttribute("author");
var memoAttributeText=xmlDoc.createTextNode("Pat Coleman");
var toElement=xmlDoc.createElement("to");
var toElementText=xmlDoc.createTextNode("Carole Poland");
memoAttribute.appendChild(memoAttributeText);
xmlDoc.appendChild(rootElement);
rootElement.setAttributeNode(memoAttribute);
rootElement.appendChild(toElement);
toElement.appendChild(toElementText);

The following code is in VBScript.

Set xmlDoc = CreateObject("Msxml2.DOMDocument")
Set rootElement=xmlDoc.createElement("memo")
Set memoAttribute=xmlDoc.createAttribute("author")
Set memoAttributeText=xmlDoc.createTextNode("Pat Coleman")
Set toElement=xmlDoc.createElement("to")
Set toElementText=xmlDoc.createTextNode("Carole Poland")
xmlDoc.appendChild(rootElement)
rootElement.setAttributeNode(memoAttribute)
rootElement.appendChild(toElement)
toElement.appendChild(toElementText)

Although you can read the textual content of a text node using its nodeValue property, it is more common to use the text property of the IXMLDOMElement object to avoid problems created by elements containing multiple text, CDATA section, and entity reference nodes. The normalize method of IXMLDOMElement can also simplify text processing.

For more information on properties and methods of IXMLDOMText, see IXMLDOMText.

CDATA Sections

CDATA sections allow developers to include the markup characters <, >, and & within element content without using character or entity references. Scripts, style sheets, program code, and sample XML code are frequently contained in CDATA sections. The IXMLDOMCDATASection object behaves like a text node, but preserves knowledge of its special status, making it easy to preserve CDATA sections through multiple load-and-save cycles.

CDATA sections behave like text nodes, except that they cannot be used inside of attribute nodes. CDATA sections may be mixed with text nodes, entity references, and other content containers, and can appear as child nodes of elements, document fragments, entity references, and entities.

The following JScript fragment creates an element named <example> whose contents are protected by a CDATA section using the createCDATASection method of DOMDocument.

var demoElement=xmlDoc.createElement("example");
var demoContent=xmlDoc.createCDATASection("<sample>This is an element</sample>");
demoElement.appendChild(demoContent);

The following code appears in VBScript.

Set demoElement=xmlDoc.createElement("example")
Set demoContent=xmlDoc.createCDATASection("<sample>This is an element</sample>")
demoElement.appendChild(demoContent)

CDATA sections also have an impact on Microsoft XML Parser (MSXML) white space handling. For more information, see Preserving Markup Characters by Using CDATA Sections.

For more information about properties and methods of IXMLDOMCDATASection, see the IXMLDOMCDATASection.

Processing Instructions

Processing instructions provide a loosely-structured mechanism for conveying application-specific information within a document. Processing instructions can appear within document, element, document fragment, entity reference, or entity nodes. They have only two components — a name (also called the target) and a value. The value may contain content that looks like attribute values (often called pseudo-attributes), but this content is stored as simple text.

Processing instructions can appear in the document content — within the root element or an element that is the descendant of the root element — or they can appear before or after the root element. The <?xml-stylesheet?> processing instruction, used to connect XML documents to cascading style sheets or XSL Transformations (XSLT) style sheets, usually appears in the prolog.

The following JScript example identifies which style sheet to use in a processing instruction in the prolog.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var stylePI=xmlDoc.createProcessingInstruction("xml-stylesheet",
  ' type="text/xsl" href="show_book.xsl"');
xmlDoc.appendChild(stylePI);

The following code is in VBScript.

Set xmlDoc = CreateObject("Msxml2.DOMDocument")
Set stylePI = xmlDoc.createProcessingInstruction("xml-stylesheet",
  "type=""text/xsl"" href=""show_book.xsl""")
xmlDoc.appendChild(stylePI)

The XML document begins with the following.

<?xml-stylesheet type="text/xsl" href="show_book.xsl"?>

The target of a processing instruction can be retrieved through its nodeName property while the rest of the processing instruction is stored in the nodeValue property. MSXML treats the XML declaration as a processing instruction within its DOM representation. This can have a significant effect on character encoding.

For more information about properties and methods of XMLDOMProcessingInstruction objects, see the IXMLDOMProcessingInstruction.

Comments

While processing instructions provide support for unstructured application-oriented information, comments provide a place for unstructured human-readable information. Comments do not have names, only content, and generally represent information that applications should ignore.

Comments are represented by IXMLDOMComment objects, which are created using the createComment method of DOMDocument. Comments can appear before, after, or within the root element. For example, the following code creates a comment that says "catalog last updated 2000-11-01".

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var dateComment=xmlDoc.createComment("catalog last updated 2000-11-01");
xmlDoc.appendChild(dateComment);

The following code is in VBScript.

Set xmlDoc = CreateObject("Msxml2.DOMDocument")
Set dateComment=xmlDoc.createComment("catalog last updated 2000-11-01")
xmlDoc.appendChild(dateComment)

The contents of an IXMLDOMComment object are always stored in its nodeValue property.

For more information about properties and methods of IXMLDOMComment, see IXMLDOMComment.

Entity References

Entity references are used to insert references to entities declared in an XML document type declaration. MSXML will expand all entity references used in a document as it parses them, but applications can insert entity references into document object models intended for export as XML documents.

The following JScript fragment creates a header element that contains the text Jay Fluegel & Mindy Martin, expressed as "Jay Fluegel ", the entity reference "amp", and " Mindy Martin".

var headerElement=xmlDoc.createElement("header");
var headerStart=xmlDoc.createTextNode("Jay Fluegel ");
var headerMiddle=xmlDoc.createEntityReference("amp");
var headerEnd=xmlDoc.createTextNode(" Mindy Martin");
headerElement.appendChild(headerStart);
headerElement.appendChild(headerMiddle);
headerElement.appendChild(headerEnd);

The following code is in VBScript.

Set headerElement=xmlDoc.createElement("header")
Set headerStart=xmlDoc.createTextNode("Jay Fluegel ")
Set headerMiddle=xmlDoc.createEntityReference("amp")
Set headerEnd=xmlDoc.createTextNode(" Mindy Martin")
headerElement.appendChild(headerStart)
headerElement.appendChild(headerMiddle)
headerElement.appendChild(headerEnd)

For more information about properties and methods of IXMLDOMEntityReference, see IXMLDOMEntityReference.

Document Fragments

Document fragments are DOM objects that do not correspond precisely to a particular construct in XML 1.0. They represent a portion, not necessarily well-formed, of an XML document. Document fragments provide programmers with a tool for storing nodes like a DOMDocument object with fewer restrictions and overhead.

IXMLDOMDocumentFragment must be created using the createDocumentFragment method of the DOMDocument object. The content stored in the document fragment remains, but the document fragment placeholder disappears when inserted into a document tree.

For more information about properties and methods of XMLDOMDocumentFragment, see IXMLDOMDocumentFragment.

Document Type

The document type node represents the information provided by the DOCTYPE declaration, if one appears. The IXMLDOMDocumentType object, accessible through the doctype property of the DOMDocument object, is read-only. This object provides access to the entities and notations that have been declared in the document type definition (DTD) of the document. Its name property identifies the root element of the document.

For more information about properties and methods of IXMLDOMDocumentType, see the IXMLDOMDocumentType.

Namespaces

MSXML provides full support for XML namespaces. Because the Worldwide Web Consortium (W3C) Namespaces in XML Recommendation appeared after the DOM Level 1 was complete, namespace support in the MSXML DOM is provided through extensions to the core DOM model. Namespace support properties are provided for all nodes in the DOM, but are generally meaningful only for element and attribute nodes. For more information, see Using Namespaces in XML Documents.

The name property of a node is its qualified name, including the namespace prefix, if any. If you want just the namespace prefix, the prefix property includes that information, while the base name, leaving off the prefix, is available through the baseName property. The namespace URI to which the prefix refers is available through the namespaceURI property.

To create namespace declarations, you must create attributes beginning with xmlns as defined by the Namespaces in XML specification.

See Also

Attributes | CDATA Sections | Comments | Document Map | DOCTYPE Declaration | Elements | Entity References | IXMLDOMNamedNodeMap | Processing Instructions | XML Declaration


Using DOMDocument

The DOMDocument object is the foundation of the XML Document Object Model (DOM). It exposes properties and methods that allow you to navigate, query, and modify the content and structure of an XML document.

The following topics describe ways to use the DOMDocument object.

  • Creating a DOMDocument Object
  • Loading and Saving XML
  • Getting and Setting Parse Flags
  • Gathering Document Information
  • Accessing the Document Tree
  • Creating New Nodes


Creating a DOMDocument Object

Before you can parse or create XML documents using the Document Object Model (DOM), you must create a DOMDocument object. After you have created that object, you can use it to load, parse, navigate, and manipulate XML files.

To create a new, empty DOMDocument object

Use the following Microsoft® JScript® code.

var mydoc = new ActiveXObject("Msxml2.DOMDocument");

Use the following Microsoft Visual Basic® Scripting Edition (VBScript) code.

Dim xmldoc
Set xmldoc = CreateObject("Msxml2.DOMDocument")

Use the following Microsoft Visual Basic code.

Set xmldoc = New DOMDocument30

See Also

IXMLDOMDocument/DOMDocument


Loading and Saving XML

The Microsoft® XML Parser (MSXML) provides two methods for loading XML documents into the Document Object Model (DOM) and one method and one property for serializing that object model back into an XML stream. The load and loadXML methods parse documents into a DOM. The save method and xml property convert the DOM back into an XML document. The load and save methods are used to retrieve information from outside a script, while the loadXML method and xml property are generally used inside scripts, parsing and returning XML strings found inside.

Use the load method to load an XML file by path name, URL, or from a Microsoft Internet Information Services (IIS) Request object.

The following example loads an XML file by URL.

XMLDoc.load("http://www.example.com/reports.xml")

The document object, XMLDoc, will load the reports.xml document, parse it, and, depending on the content of the document, create an object tree representing the document or report an error.

By default, the loading and parsing of an XML file occurs asynchronously. To load the XML file synchronously, set the async property to False. This forces the loading of the entire XML document before processing continues. To abort an asynchronous download, call the abort method on the document object.

You can also load an XML file as a string using the loadXML method.

XMLDoc.loadXML("<customer><first_name>Joe</first_name>
  <last_name>Smith</last_name></customer>")

To save a parsed XML document to a file or another object, use the save method. The save method takes either a file name as a string, an Active Server Pages (ASP) Response object, a DOMDocument object, or any custom object that supports persistence. The following Microsoft Visual Basic® Scripting Edition (VBScript) example is part of an ASP page that saves the XML document to a file.

<%
  dim xmldoc
  set xmldoc = Server.CreateObject("Msxml2.DOMDocument")
  xmldoc.async = false
  xmldoc.load(Request)
  xmldoc.save(Server.MapPath("sample.xml"))
%>

The following example is in Microsoft JScript®.

<%
  var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
  xmldoc.async = false;
  xmldoc.load(Request);
  xmldoc.save(Server.MapPath("sample.xml"));
%>

You can use the xml property of DOMDocument to retrieve the XML document as a string. This allows you to retrieve a Unicode string representation of the XML document model. An ASP script that uses the XML parser to process information sent in the Request object is shown in VBScript.

<%
  dim xmldoc
  set xmldoc = Server.CreateObject("Msxml2.DOMDocument")
  xmldoc.async = false
  xmldoc.load(Request)
  xmlAsString=xmldoc.xml
%>

The following example is in JScript.

<%
  var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
  xmldoc.async = false;
  xmldoc.load(Request);
  xmlAsString=xmldoc.xml;
%>

See Also

async Property | load Method | loadXML Method | save Method


Getting and Setting Parse Flags

While the Microsoft® XML Parser (MSXML) is a single library, there are times when you may want to parse an XML document in different ways. The XML recommendation allows parsers to validate or not validate documents, and allows nonvalidating parsers to skip the retrieval of external resources. In addition, you may want the parser to process the document while your code continues or remove extraneous white space from your documents.

The DOMDocument object exposes four properties that allow the user to change parsing behavior at run time.

  • async
  • validateOnParse
  • resolveExternals
  • preserveWhiteSpace

Each of these properties takes and returns a Boolean value. The default value for async, validateOnParse, and resolveExternals is True. The default value for preserveWhiteSpace, which specifies whether to honor the xml:space attribute in XML documents, is False.

The following Microsoft Visual Basic® Scripting Edition (VBScript) sample code loads and parses an XML file synchronously; however, the XML document is not validated as it is parsed.

dim XMLDoc
set XMLDoc = Server.CreateObject("Msxml2.DOMDocument")
XMLDoc.async = false
XMLDoc.validateOnParse = false
XMLDoc.load("sample.xml")

The following example is in Microsoft JScript®.

var XMLDoc = new ActiveXObject("Msxml2.DOMDocument");
XMLDoc.async = false;
XMLDoc.validateOnParse = false;
XMLDoc.load("sample.xml");
Note Although not explicitly indicated in this code, by default, the parser will resolve externals and will not honor the value of the xml:space attribute.

Asynchronous parsing allows your application to do other things, such as display a progress bar, while the file is being parsed. After loading the XML document but before manipulating or reading it, be sure to check the readyState property to ensure that the document has been fully loaded and that the Document Object Model (DOM) is available.

See Also

readyState Property (DOMDocument)


Gathering Document Information

These properties can be used to get the following information about the document parsing process.

  • doctype

    The document type definition (DTD) accompanying the document.

  • implementation

    The implementation for the document.

  • parseError

    The last error to occur while parsing.

  • readyState (DOMDocument)

    Information about the state of the XML document.

  • url

    The URL, if any, of the XML file being loaded and parsed.

For more information about error reporting, see IXMLDOMParseError.

The readyState property is critical for programs that use the Microsoft® XML Parser (MSXML) asynchronously to improve performance. When loading XML documents asynchronously, your programs may need to check the state of the parsing process. MSXML provides four states, numbered one through four: loading, loaded, interactive (parsing), and completed. The following Microsoft JScript® and HTML example demonstrates the sequence of ready states when asynchronously loading a document.

<script>
var xmldoc;
function Load()
{
    xmldoc = new ActiveXObject("Msxml2.DOMDocument");
    xmldoc.onreadystatechange = CheckState;
    xmldoc.load(URL.value);
}
function CheckState()
{
    var state = xmldoc.readyState;
    RESULTS.innerHTML += "readyState = " + state + "<BR>"
    if (state == 4)
    {
      var err = xmldoc.parseError;
        if (err.errorCode != 0)
          RESULTS.innerHTML += err.reason + "<BR>"
        else
          RESULTS.innerHTML +="success" + "<BR>"
    }
}
</script>
URL: <input type=text size=60 id=URL>
<input type=button value=LOAD onclick="jscript:Load()">
<div id=RESULTS style="color:red; font-weight:bold;"></div>


Accessing the Document Tree

You can access the tree for an XML document either by beginning at the root element and moving from node to node or by querying for a specific node or nodes. You can navigate to the root element of the document by using the documentElement property. This property returns the root element as an IXMLDOMNode.

The following books.xml file is the same as the file used in the document map.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="show_book.xsl"?>
<!DOCTYPE catalog SYSTEM "catalog.dtd">
<!--catalog last updated 2000-11-01-->
<catalog xmlns="http://www.example.com/catalog/">
  <book id="bk101">
     <author>Gambardella, Matthew</author>
     <title>XML Developer's Guide</title>
     <genre>Computer</genre>
     <price>44.95</price>
     <publish_date>2000-10-01</publish_date>
     <description><![CDATA[An in-depth look at creating applications with XML, using <, >,]]> and &amp;.</description>
  </book>
  <book id="bk109">
     <author>Kress, Peter</author>
     <title>Paradox Lost</title>
     <genre>Science Fiction</genre>
     <price>6.95</price>
     <publish_date>2000-11-02</publish_date>
     <description>After an inadvertant trip through a Heisenberg Uncertainty Device, James Salway discovers the problems of being quantum.</description>
  </book>
</catalog>

You can walk the tree to the first level of elements contained by the root using Microsoft® Visual Basic® Scripting Edition (VBScript).

Dim root
Dim xmlDoc
Dim child

Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.async = False
xmlDoc.load("c:\books.xml")
'Set root to the XML document's root element, COLLECTION:
Set root = xmlDoc.documentElement
'Walk from the root to each of its child nodes:
For Each child In root.childNodes
  MsgBox child.text
Next

When run, this example displays the text of each of the root's child nodes (book elements) as a separate text message.

You can use the following methods to navigate to a specific node or nodes deep within the tree.

  • nodeFromID method

    The nodeFromID method takes a unique ID, as identified by an XML schema or document type definition (DTD), and returns the node corresponding to that specific ID.

  • getElementsByTagName method (DOMDocument)

    The getElementsByTagName method takes a string representing a specific tag name and returns all element nodes with this tag name.

You can use the following code to retrieve all element nodes named "AUTHOR" in books.xml.

Dim ElemList
Dim xmlDoc
Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.async = False
xmlDoc.load("c:\xml\books.xml")
Set ElemList = xmlDoc.getElementsByTagName("AUTHOR")
  For i=0 To (ElemList.length -1)
    MsgBox ElemList.item(i).xml
  Next

The selectNodes method of the IXMLDOMNode object offers a more flexible way of accessing nodes using XML Path Language (XPath).

See Also

Document Map | documentElement Property | IXMLDOMNode | selectNodes Method


Creating New Nodes

The DOMDocument object exposes the createNode method, which allows you to create a qualified node by supplying the node type, name, and namespaceURI of the new node.

DOMDocument also exposes the following eight methods, which allow you to create specific Document Object Model (DOM) nodes.

  • createAttribute method
  • createCDATASection method
  • createComment method
  • createDocumentFragment method
  • createElement method
  • createEntityReference method
  • createProcessingInstruction method
  • createTextNode method

These methods return objects and interfaces and are described in the XML Reference. These specific objects and interfaces expose properties and methods associated with that node. For example, the following sample code assigns an XMLDOMElement object with the name of "item" to the variable xmlElem.

xmlElem = xmlDoc.createElement("item")

You can then add an attribute to that element by calling the setAttribute method and passing that method a string containing the attribute name and a string containing the attribute value.

xmlElem.setAttribute("id","bar")

Using books.xml again as an example, the following code creates a new element, PAGES, and uses the appendChild method to add it to the second child node of the root, COLLECTION. It then sets the text property for the new element to "400".

Dim xmlDoc
Dim root
Dim newElem
Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.async = False
xmlDoc.load("c:\books.xml")
Set root = xmlDoc.documentElement
Set newElem = xmlDoc.createElement("PAGES")
root.childNodes.item(1).appendChild newElem
root.childNodes.item(1).lastChild.text = "400"
MsgBox root.childNodes.item(1).xml

You can assign a new document to a document object by assigning the document a new root element using the documentElement property.

XMLDoc.documentElement = XMLNode

In order for this operation to work, XMLNode must be an element type node.

Note Assigning the document object a new document element does not change the other children of the document. For example, the doctype element does not change.

See Also

Accessing the Document Tree | appendChild Method | createNode Method | documentElement Property | setAttribute Method | XML Reference


Using IXMLDOMNode

IXMLDOMNode is the principal object within the Document Object Model (DOM). Elements, attributes, comments, processing instructions, and every other document component can be represented as an IXMLDOMNode. The DOMDocument object is itself an IXMLDOMNode object, as are the members of node lists and named node maps. The following topics discuss how to use IXMLDOMNode.

  • Gathering Information About a Node
  • Getting and Setting Data Within a Node
  • Navigating the Tree
  • Manipulating the Children of a Node
  • Transforming a Node

See Also

IXMLDOMNode


Gathering Information About a Node

These properties can be used to get the following information about a node.

  • hasChildNodes

    If the node has any children.

  • namespaceURI

    The namespace to which the node belongs.

  • nodeName

    The name of the node.

  • nodeType

    The type of the node.

  • nodeTypeString

    The type of the node.

  • parsed

    If the node has been parsed.

  • specified

    If the node is explicitly specified in the XML file or implied within the document type definition (DTD) or XML Schema.

  • xml

    The string representation of the node.

The following sample code tests the nodeTypeString property to see if the node is of type "element". If the node is of type "element", the string representation of the node is loaded into a new document object through the loadXML method, creating a document fragment.

if (xmlNode.nodeTypeString == "element")
  XMLDoc.loadXML(xmlNode.xml)

You can use the following code if you prefer to work with the numeric representation.

if (xmlNode.nodeType == 1)
  XMLDoc.loadXML(xmlNode.xml)

You can get the name of a node by checking the nodeName property.

currentNodeName=xmlNode.nodeName

You can use the following code to find nodes without child nodes and retrieve their content as a string.

if (xmlNode.hasChildren == false)
  currentNodeContent=xmlNode.xml

You can use the following code to limit the nodes processed to nodes from specific namespaces.

if (xmlNode.namespaceURI == "http://www.example.com/catalog")
  'catalog-specific processing here


Getting and Setting Data Within a Node

Data marked up as text within elements, attributes, comments, and processing instructions is exposed in the Document Object Model (DOM) as node values.

The following code sets the value of an attribute to "hello world".

newAttNode = myElementNode.createAttribute("newAtt")
newAttNode.nodeValue = "hello world"

There are three ways to access text within an element node.

  • The nodeValue property provides direct access to values of certain types of nodes, including attributes, text nodes, comments, processing instructions, and CDATA sections. Navigate down to the element's children (the text nodes within) and call nodeValue.
  • The text property returns the text within the element. The text within an element can also be changed using the text property, but this will overwrite any child elements.

    The following sample code tests to see if the text within the element elem1 is equal to "hello world". If so, the element is assigned the text "hi! world".

    if (elem1.text == "hello world")
  elem1.text = "hi! world"
  • The nodeTypedValue property is part of the data type support built into the Microsoft® XML Parser (MSXML) and returns the typed value of the node. This property is only for typed elements. The dataType property, which returns the data type of the element, can be used in conjunction with this property. The nodeTypedValue and datatype properties can both be set. However, the parser will return an error if the new nodeTypedValue is of the wrong data type or if the new data type does not match the nodeTypedValue. For more information about data type support, see XDR Data Types Reference.

See Also

dataType Property | nodeValue Property | nodeTypedValue Property | text Property


Navigating the Tree

The Document Object Model (DOM) treats the contents of documents as a collection of nodes of various types. Some nodes contain other nodes, or groups of nodes, building a structure commonly referred to as the document tree. Programs that access or manipulate the information stored in XML documents through the DOM must navigate this tree structure.

From an IXMLDOMNode object, you can navigate directly to its parent node (parentNode), children (childNodes, firstChild, lastChild), siblings (previousSibling, nextSibling), or the document object to which the node belongs (ownerDocument). If the node is of type element, attribute, or entityReference, you can call the definition property to navigate to the schema definition of the node. In addition, if the node is of type element, processingInstruction, documentType, entity, or notation, you can navigate to the attributes on the node using the attributes property.

The following code tests to see if the elem1 element has any element children. If so, it navigates from elem1 to that element's first child. The text of that first child is then changed to "I'm the first child of elem1".

if (elem1.hasChildNodes == true && elem1.firstChild.nodeTypeString == "element")
  elem1.firstChild.text = "I'm the first child of elem1"

To navigate to nodes other than the first or last sibling, you can start from the first or last child and use the previousSibling or nextSibling methods to move forward or backward through the list.

wantedNodeCount=2
currentNode=1
set wantedNode=elem1.firstChild
Do While currentNode<wantedNodeCount
  set wantedNode=wantedNode.nextSibling
  currentNode=currentNode+1
Loop

The following is an example in Microsoft® JScript®.

wantedNodeCount=2;
currentNode=1;
wantedNode=elem1.firstChild;
while (currentNode<wantedNodeCount) {
  wantedNode=wantedNode.nextSibling;
  currentNode++;
}

In either case, the variable wantedNode contains the desired node, and can be used for other processing or navigation. With a few additional comparisons, you can use techniques like these to find nodes that meet specific type and content criteria. If you prefer to walk through the list of child nodes using numeric references, use the IXMLDOMNodeList object returned by the childNodes property.

It is also possible to navigate to other nodes in the tree using the selectNodes and selectSingleNode methods. These methods take an XML Path Language (XPath) expression as an argument and return the node or nodes that match that query. For more information about XPath, see XPath Syntax.

See Also

attributes Property | childNodes Property | definition Property | firstChild Property | lastChild Property | nextSibling Property | ownerDocument Property | parentNode Property | previousSibling Property |selectNodes Method | selectSingleNode Method


Manipulating the Children of a Node

The IXMLDOMNode object exposes four methods that allow you to manipulate the children of a node. Each of these methods takes an IXMLDOMNode object as an argument.

  • appendChild method
  • replaceChild method
  • removeChild method
  • insertBefore method

The following code takes a new element that is created using createElement and adds that as the last child of elem1.

newChild = XMLDoc.createElement("last_child")
elem1.appendChild(newChild)

The appendChild method always adds the node to the end of the list of children. To insert the node elsewhere in the child node list, use the insertBefore method. This method takes two parameters: the node to be inserted and the node before which the new child is to be inserted.

The following Microsoft® Visual Basic® Scripting Edition (VBScript) example loads books.xml and creates a new element, pages. Then, using a reference to the first child of the first node contained by the document element as the reference point (refElem), it inserts the new element with the insertBefore method.

Dim xmlDoc
Dim root
Dim newElem
Dim refElem
Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.async = False
xmlDoc.load("c:\xmlinact\books.xml")
'create new element
Set newElem = xmlDoc.createElement("pages")
'start from the root element
Set root = xmlDoc.documentElement
'find the first child of the root element (using collection syntax)
Set firstElem=root.childNodes.item(1)
'find the first child of the first child (using property syntax)
Set refElem = firstElem.firstChild
'insert our new pages element
root.childNodes.item(1).insertBefore newElem, refElem
'report the content of the first child of the root element
MsgBox firstElem.xml

The following is an example in Microsoft JScript®.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("c:\\books.xml");
//create new element
var newElem = xmlDoc.createElement("pages");
//start from the root element
var root = xmlDoc.documentElement;
//find the first child of the root element (using collection syntax)
var firstElem=root.childNodes.item(1);
//find the first child of the first child (using property syntax)
var refElem = firstElem.firstChild;
//insert our new pages element
root.childNodes.item(1).insertBefore(newElem, refElem);
//report the content of the first child of the root element
alert(firstElem.xml);

The following VBScript example uses the removeChild method to remove a child node. Most of the code is similar to the preceding example, but this script removes an element rather than creating and adding one.

Dim xmlDoc
Dim root
Dim oldChild
Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.async = False
xmlDoc.load("c:\books.xml")
Set root = xmlDoc.documentElement
'find the first child of the root element (using collection syntax)
Set firstElem=root.childNodes.item(1)
Set oldChild = firstElem.firstChild
firstElem.removeChild oldChild
MsgBox firstElem.xml

The following is an example in JScript.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("c:\\books.xml");
//start from the root element
var root = xmlDoc.documentElement;
//find the first child of the root element (using collection syntax)
var firstElem=root.childNodes.item(1);
//pick the element to remove
var oldChild = firstElem.firstChild;
//remove the element
firstElem.removeChild (oldChild);
//report the content of the first child of the root element
alert(firstElem.xml);

See Also

Accessing the Document Tree


Transforming a Node

The transformNode and transformNodeToObject methods can be used to transform an XML node into a string or object using XSL Transformations (XSLT). For more information about transforming nodes using XSLT, see the XSLT Developer's Guide.

See Also

transformNode Method | transformNodeToObject Method


Using IXMLDOMNodeList

The IXMLDOMNodeList object is returned by the childNodes collection and the selectNodes and getElementsByTagName methods.

The following topics discuss how to use the XMLDOMNodeList object.

  • Gathering Information About the Node List
  • Navigating the Node List

See Also

IXMLDOMNodeList


Gathering Information About the Node List

You can retrieve the length of the node list from the length property. Among other things, the length can be used for iterating through the list of children. For example, the following Microsoft® JScript® code loops through the children of elem1, searching for a child element with the text value of "hello world". If such a child exists, the index of that child is assigned to the variable "helloWorldIndex".

for (i = 0;i < elem1.childNodes.length;i++){
  if (elem1.childNodes.item(i).text == "hello world")
    helloWorldIndex = i;
  }

In Microsoft Visual Basic® Scripting Edition (VBScript), the same code would look like the following.

For i = 0 to elem1.childNodes.length - 1
  if (elem1.childNodes.item(i).text = "hello world") Then
    helloWorldIndex = i
Next

You can also move through the node list using the nextNode method.

See Also

length Property (IXMLDOMNodeList)


Navigating the Node List

You can retrieve a specific member of the node list by using the item method. The item method takes a number corresponding to a node's position within the node list. To retrieve the first node in the node list, call item(0). It is also possible to navigate through the node list using the nextNode method, which returns the next node in the node list.

The following Microsoft® JScript® code performs the same task as the code in the previous topic.

currentNode = elem1.childNodes.nextNode;
while (currentNode != null) {
  if (currentNode.text == "hello world")
    helloWorldNode = currentNode;
  currentNode = elem1.childNodes.nextNode;
  }

This is the same example in Microsoft Visual Basic® Scripting Edition (VBScript).

Set currentNode = elem1.childNodes.nextNode
Do While currentNode <> null
  If currentNode.text = "hello world" Then
    helloWorldNode = currentNode
  End If
  currentNode = elem1.childNodes.nextNode
Loop

The currentNode is modified using the node returned by elem1.childNodes.nextNode. The initial position of the node list is defined to be before the first node. Therefore, the first time nextNode is called on the node list, the first node is returned. The code tests for currentNode != null. If the current node is the last node in the list or the node list has no members, nextNode returns null.

See Also

Gathering Information About the Node List | item Method (IXMLDOMNodeList) | nextNode Method (IXMLDOMNodeList)


Using IXMLDOMNamedNodeMap

An IXMLDOMNamedNodeMap object is returned by the attributes property. The IXMLDOMNamedNodeMap object differs from the node list in that it is a collection of nodes that can be accessed by name as well as number. Because the order of attributes is not important in XML, this can make attribute processing easier.

The following topics discuss how to use the IXMLDOMNamedNodeMap object.

  • Gathering Information About the Named Node Map
  • Navigating the Named Node Map
  • Manipulating a Named Node Map

See Also

attributes Property | IXMLDOMNamedNodeMap


Gathering Information About the Named Node Map

Like the IXMLDOMNodeList object, the IXMLDOMNamedNodeMap object exposes the length property. This property returns the number of members in the named node map.

See Also

length Property (IXMLDOMNamedNodeMap)


Navigating the Named Node Map

As with a node list, you can access members of the named node map by index using the item method. You can also access the members of a named node map name by using the following methods.

  • getNamedItem method

    The getNamedItem method takes the name of the desired node as a parameter.

    The following code retrieves the value of the ID attribute on the elem1 element and assigns that value to the variable idValue.

    idValue = elem1.attributes.getNamedItem("ID").nodeValue
  • getQualifiedItem method

    The getQualifiedItem method takes the name and namespace URI of the desired node.

Each method returns an IXMLDOMNode object.

Like the IXMLDOMNodeList, IXMLDOMNamedNodeMap exposes the nextNode property.

See Also

item Method (IXMLDOMNamedNodeMap)


Manipulating a Named Node Map

You can use the following methods to manipulate named node maps.

  • setNamedItem method

    The setNamedItem method takes an XML node object as a parameter, adding that node to the named node map. If an attribute already exists with the same name as that specified by the nodeName of the node added, the old attribute is replaced. The following code creates a new attribute node with the name ID and adds it to the attributes of elem1.

    idAtt = XMLDoc.createAttribute("ID")
elem1.setNamedItem(idAtt)
  • removeNamedItem method

    The removeNamedItem method takes a node name as a parameter, removing the node with that name.

  • removeQualifiedItem method

    The removeQualifiedItem method takes a node name and namespace URI as its parameters, removing the corresponding attribute.

Alternatively, element nodes also support the setAttribute, setAttributeNode, removeAttribute, and removeAttributeNode methods if you prefer to treat attributes as properties of elements rather than as members of a collection contained by an element.


XML DOM Persistence

Information stored in an XML Document Object Model (DOM) can be serialized to an XML file, and information stored in an XML file can be opened into a DOM. XML files provide an easily exchanged, stored, and processed format for persisting information.

For scripting purposes, persistence of object models as files is handled by the following property and methods.

  • load method
  • loadXML method
  • save method
  • xml property

For Microsoft® Visual Basic® and C/C++ programmers, DOM persistence is handled by the following methods and objects/interfaces.

  • load method
  • loadXML method
  • save method
  • xml property
  • IPersistStreamInit interface (see IXMDOMDocument/DOMDocument)
  • IPersistMoniker interface (see IXMDOMDocument/DOMDocument)
  • IStream interface (see IXMDOMDocument/DOMDocument)


White Space and the DOM

To achieve maximum performance, when a text file is opened with the xmlDoc.load or xmlDoc.loadXML methods (where xmlDoc is an XML DOM document), the parser strips most white space from the file unless specifically directed otherwise; the parser notes within each node whether one or more spaces, tabs, newlines, or carriage returns follow the node in the text by setting a flag.

As a result, a node in an XML DOM document "knows" that at least one occurrence of white space follows or precedes it, but does not know exactly how much white space there was. This method is efficient, reducing both the size of each XML file and the number of calculations required to redisplay the XML in a browser.

However, because this information is lost, an XML document stored in this manner can lose formatting information. Tabs, in particular, can be lost because they are not formally recognized in the default mode as anything but white space.

XSL Transformations (XSLT) uses the XML Document Object Model (DOM), not the source document, to guide its transformation. Because the white space has already been stripped to process the XML into the DOM, white space characters are lost even before the transformation takes place. Most of the XSLT-related methods for specifying white space in the source data document or style sheets are applied too late to make a difference in formatting.

The preserveWhiteSpace property tells the XML parser whether or not to convert white space from the initial source file that acts against the XML DOM. If explicitly set (the default is False), it must always be set prior to loading a file; otherwise, the default is to strip white space characters and reduce the file to the smallest possible stream. When preserveWhiteSpace is set to True, the XML document retains all of the characters within the file when converted into a DOM.

If you set the preserveWhiteSpace property from True to False then back to True for a given DOM document, the spaces will not reappear — setting the property to False actually removes the space from the DOM, which cannot reconstruct it.

If you are working with XML as a data format streamed to some other process, disable preserveWhiteSpace by setting it, or allowing it to default, to False. If retaining positional information is important, for example, in conversions to non-XML formats like tab-separated data, set preserveWhiteSpace to True. Be aware this option increases the number of characters and places more demands on the browser.


XML Tutorial

List of Lessons

This tutorial consists of a set of interactive lessons that walk you through typical Extensible Markup Language (XML) authoring and development tasks.

You will be able to read the lessons in Microsoft® Internet Explorer 3.0, 4.0, and other browsers, but the interactive elements and demos require Internet Explorer 5.0 and later.

  • Lesson 1: Authoring XML Elements
  • Lesson 2: Authoring XML Documents
  • Lesson 3: Authoring XML Data Islands
  • Lesson 4: Using the XML Object Model
  • Lesson 5: Using XML Namespaces
  • Lesson 6: Authoring XML Schemas
  • Lesson 7: Using Data Types Within XML Documents
  • Lesson 8: Accessing Typed XML Values
  • Lesson 9: Using the C++ XML Data Source Object
  • Lesson 10: Using the Master/Detail Feature with the C++ XML Data Source Object


Lesson 1: Authoring XML Elements

What is an XML element?

XML is a meta-markup language, a set of rules for creating semantic tags used to describe data. An XML element is made up of a start tag, an end tag, and data in between. The start and end tags describe the data within the tags, which is considered the value of the element. For example, the following XML element is a <director> element with the value "Matthew Dunn."

<director>Matthew Dunn</director>

The element name "director" allows you to mark up the value "Matthew Dunn" semantically, so you can differentiate that particular bit of data from another, similar bit of data. For example, there might be another element with the value "Matthew Dunn."

<actor>Matthew Dunn</actor>

Because each element has a different tag name, you can easily tell that one element refers to Matthew Dunn, the director, while the other refers to Matthew Dunn, the actor. If there were no way to mark up the data semantically, having two elements with the same value might cause confusion.

In addition, XML tags are case-sensitive, so the following are each a different element.

<City> <CITY> <city>

Attributes

An element can optionally contain one or more attributes. An attribute is a name-value pair separated by an equal sign (=).

<CITY ZIP="01085">Westfield</CITY>

In this example, ZIP="01085" is an attribute of the <CITY> element. Attributes are used to attach additional, secondary information to an element, usually meta information. Attributes can also accept default values, while elements cannot. Each attribute of an element can be specified only once, but in any order.

Try it!

In the following text box, type the title of a favorite movie and then click Continue.

In the box below, enter a single-word description of the word (movie, film, screenplay, title, and so on) and then click the Continue button.

You have just created the following XML element:

Check the syntax

Because XML is a highly structured language, it is important that all XML be well-formed. That is, the XML must have both a start tag and end tag, and must be authored using the proper syntax. In the following box, create an XML element with a start tag, an end tag, and a value on a single line. Click the Well-formed? button to see if your XML is correct.


Lesson 2: Authoring XML Documents

What is an XML document?

A basic XML document is simply an XML element that can, but might not, include nested XML elements.

For example, the XML <books> element is a valid XML document:

<books>
  <book isbn="0345374827">
    <title>The Great Shark Hunt</title>
    <author>Hunter S. Thompson</author>
  </book>
</books>

Authoring guidelines

There are some things to remember when constructing a basic XML document.

  • All elements must have an end tag.
  • All elements must be cleanly nested (overlapping elements are not allowed).
  • All attribute values must be enclosed in quotation marks.
  • Each document must have a unique first element, the root node.

Try it!

In the following text box, create an XML document that contains both <element> and <attribute> nodes. Click the Well-formed? button to see whether your XML document conforms to the XML specification.


Lesson 3: Authoring XML Data Islands

What is an XML data island?

A data island is an XML document that exists within an HTML page. It allows you to script against the XML document without having to load it through script or through the <OBJECT> tag. Almost anything that can be in a well-formed XML document can be inside a data island.

The <XML> element marks the beginning of the data island, and its ID attribute provides a name that you can use to reference the data island.

The XML for a data island can be either inline:

<XML ID="XMLID">
  <customer>
    <name>Mark Hanson</name>
    <custID>81422</custID>
  </customer>
</XML>

or referenced through a SRC attribute on the <XML> tag:

<XML ID="XMLID" SRC="customer.xml"></XML>

You can also use the <SCRIPT> tag to create a data island.

<SCRIPT LANGUAGE="xml" ID="XMLID">
  <customer>
    <name>Mark Hanson</name>
    <custID>81422</custID>
  </customer>
</SCRIPT>

Authoring guidelines

Simply author an XML document, place that XML document within an <XML> element, and give that <XML> element an ID attribute.

Try it!

In the following text box, type a well-formed XML document.

Type an ID for the data island.

Click the Insert Data Island button to display an HTML page with your data island inserted.


Lesson 4: Using the XML Object Model

What is the XML object model?

The XML object model is a collection of objects that you use to access and manipulate the data stored in an XML document. The XML document is modeled after a tree, in which each element in the tree is considered a node. Objects with various properties and methods represent the tree and its nodes. Each node contains the actual data in the document.

How do I access the nodes in the tree?

You access nodes in the tree by scripting against their objects. These objects are created by the XML parser when it loads and parses the XML document. You reference the tree, or document object, by its ID value. In the following example, MyXMLDocument is the document object's ID value. The document object's properties and methods give you access to the root and child node objects of the tree. The root, or document element, is the top-level node from which its child nodes branch out to form the XML tree. The root node can appear in the document only once.

Run the mouse over the following data island to reveal the code required to access each node. The root node is <class>, and its child node is <student>, which has child nodes of <name> and <GPA>.

<XML ID="MyXMLDocument">
  <class>
    <student studentID="13429">
      <name>Jane Smith</name>
      <GPA>3.8</GPA>
    </student>
  </class>
</XML>

The following list is a sample of the properties and methods that you use to access nodes in an XML document.

Property/Method | Description
XMLDocument | Returns a reference to the XML Document Object Model (DOM) exposed by the object.
DocumentElement | Returns the document root of the XML document.
ChildNodes | Returns a node list containing the children of a node (if any).
Item | Accesses individual nodes within the list through an index. Index values are zero-based, so item(0) returns the first child node.
Text | Returns the text content of the node.

The following code shows an HTML page containing an XML data island. The data island is contained within the <XML> element.

<HTML>
  <HEAD>
    <TITLE>HTML with XML Data Island</TITLE>
  </HEAD>
  <BODY>
    <P>Within this document is an XML data island.</P>
    <XML ID="resortXML">
      <resorts>
        <resort>Calinda Cabo Baja</resort>
        <resort>Na Balam Resort</resort>
      </resorts>
    </XML>
  </BODY>
</HTML>
Calinda Cabo Baja Na Balam Resort

You access the data island through the ID value, "resortXML", which becomes the name of the document object. In the preceding example, the root node is <resorts>, and the child nodes are <resort>.

The following code accesses the second child node of <resorts> and returns its text, "Na Balam Resort."

resortXML.XMLDocument.documentElement.childNodes.item(1).text

How do I persist XML DOM tree information?

Several methods and interfaces are available for persisting DOM information.

If you are using a script language, the DOMDocument object exposes the load, loadXML, and save methods, and the xml property.

For Microsoft® Visual Basic® and C or C++ programmers, the DOMDocument interface exposes the same members as the DOMDocument object. IXMLDOMDocument also implements standard COM interfaces such as IPersistStreamInit, IPersistMoniker, and IStream.

Try it!

In the following text box, enter code to access a part of either of the preceding documents. Assume that the first document object is "MyXMLDocument" and the second is "resortXML". Then click the Access XML button to reveal the node you have referenced.

Jane Smith 3.8

See Also

DOMDocument


Lesson 5: Using XML Namespaces

What is an XML namespace?

An XML namespace is a collection of names that can be used as element or attribute names in an XML document. The namespace qualifies element names uniquely on the Web in order to avoid conflicts between elements with the same name. The namespace is identified by some Uniform Resource Identifier (URI), either a Uniform Resource Locator (URL), or a Uniform Resource Number (URN), but it doesn't matter what, if anything, it points to. URIs are used simply because they are globally unique across the Internet.

Namespaces can be declared either explicitly or by default. With an explicit declaration, you define a shorthand, or prefix, to substitute for the full name of the namespace. You use this prefix to qualify elements belonging to that namespace. Explicit declarations are useful when a node contains elements from different namespaces. A default declaration declares a namespace to be used for all elements within its scope, and a prefix is not used.

How do I declare an explicit namespace?

The following explicit declaration declares "bk" and "money" to be shorthand for the full names of their respective namespaces. The xmlns attribute is an XML keyword for a namespace declaration.

<BOOKS>
  <bk:BOOK xmlns:bk="urn:BookLovers.org:BookInfo"
           xmlns:money="urn:Finance:Money">
    <bk:TITLE>A Suitable Boy</bk:TITLE>
    <bk:PRICE money:currency="US Dollar">22.95</bk:PRICE>
  </bk:BOOK>
</BOOKS>

All elements beginning with "bk:" or "money:" are considered to be from the namespace "urn:BookLovers.org:BookInfo" or "urn:Finance:Money," respectively. Run the mouse over the XML to reveal information about the different elements.

How do I declare a default namespace?

A namespace declared without a prefix becomes the default namespace for the document. All elements and attributes in the document that do not have a prefix will then belong to the default namespace. The following example declares that the <BOOK> element and all elements and attributes within it (<TITLE>, <PRICE>, currency) are from the namespace "urn:BookLovers.org:BookInfo."

<BOOK xmlns="urn:BookLovers.org:BookInfo">
  <TITLE>A Suitable Boy</TITLE>
  <PRICE currency="US Dollar">22.95</PRICE>

Try it!

In the following text box, add an explicit namespace declaration to the <BOOK> element of the following XML document for the namespace "urn:BookLovers.org:AuthorInfo" with a prefix of "author". Click the Well-formed? button to see whether your XML document conforms to the XML specification.

<BOOKS>
  <bk:BOOK xmlns:bk="urn:BookLovers.org:BookInfo"
           xmlns:money="urn:Finance:Money">
    <bk:TITLE>A Suitable Boy</bk:TITLE>
    <bk:PRICE money:currency="US Dollar">22.95</bk:PRICE>
  </bk:BOOK>
</BOOKS>

Now, add an element to the XML above called <AUTHOR>, qualified with the namespace prefix "author", containing the book's author, "Achim Hepp". Click the Well-formed? button to see whether your XML document conforms to the XML specification.

<BOOKS>
  <bk:BOOK xmlns:bk="urn:BookLovers.org:BookInfo"
           xmlns:money="urn:Finance:Money"
           xmlns:author="urn:BookLovers.org:AuthorInfo">
    <bk:TITLE>A Suitable Boy</bk:TITLE>
    <bk:PRICE money:currency="US Dollar">22.95</bk:PRICE>
    <author:AUTHOR>Achim Hepp</author:AUTHOR>
  </bk:BOOK>
</BOOKS>


Lesson 6: Authoring XML Schemas

What is an XML Schema?

An XML Schema is an XML-based syntax for defining how an XML document is marked up. XML Schema is a schema specification recommended by Microsoft and it has many advantages over document type definition (DTD), the initial schema specification for defining an XML model. DTDs have many drawbacks, including the use of non-XML syntax, no support for datatyping, and non-extensibility. For example, DTDs do not allow you to define element content as anything other than another element or a string. For more information about DTDs, see the Worldwide Web Consortium (W3C) XML Recommendation. XML Schema improves upon DTDs in several ways, including the use of XML syntax, and support for datatyping and namespaces. For example, an XML Schema allows you to specify an element as an integer, a float, a Boolean, a URL, and so on.

The Microsoft® XML Parser (MSXML) in Microsoft Internet Explorer 5.0 and later can validate an XML document with both a DTD and an XML Schema.

How can I create an XML Schema?

Run the mouse over the following XML document to reveal the schema declarations for each node.

  <class xmlns="x-schema:classSchema.xml">
    <student studentID="13429">
      <name>James Smith</name>
      <GPA>3.8</GPA>
    </student>
  </class>

You'll notice in the preceding document that the default namespace is "x-schema:classSchema.xml." This tells the parser to validate the entire document against the schema (x-schema) at the following URL ("classSchema.xml").

The following is the entire schema for the preceding document. The schema begins with the <Schema> element containing the declaration of the schema namespace and, in this case, the declaration of the "datatypes" namespace as well. The first, "xmlns="urn:schemas-microsoft-com:xml-data"," indicates that this XML document is an XML Schema. The second, "xmlns:dt="urn:schemas-microsoft-com:datatypes"," allows you to type element and attribute content by using the dt prefix on the type attribute within their ElementType and AttributeType declarations.

<Schema xmlns="urn:schemas-microsoft-com:xml-data"
  xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <AttributeType name='studentID' dt:type='string' required='yes'/>
  <ElementType name='name' content='textOnly'/>
  <ElementType name='GPA' content='textOnly' dt:type='float'/>
  <ElementType name='student' content='mixed'>
    <attribute type='studentID'/>
    <element type='name'/>
    <element type='GPA'/>
  </ElementType>
  <ElementType name='class' content='eltOnly'>
    <element type='student'/>
  </ElementType>
</Schema>

The declaration elements that you use to define elements and attributes are described as follows.

Element | Description
ElementType | Assigns a type and conditions to an element, and what, if any, child elements it can contain.
AttributeType | Assigns a type and conditions to an attribute.
attribute | Declares that a previously defined attribute type can appear within the scope of the named ElementType element.
element | Declares that a previously defined element type can appear within the scope of the named ElementType element.

The content of the schema begins with the AttributeType and ElementType declarations of the innermost elements.

<AttributeType name='studentID' dt:type='string' required='yes'/>
<ElementType name='name' content='textOnly'/>
<ElementType name='GPA' content='textOnly' dt:type='float'/>

The next ElementType declaration is followed by its attribute and child elements. When an element has attributes or child elements, they must be included this way in its ElementType declaration. They must also be previously declared in their own ElementType or AttributeType declaration.

<ElementType name='student' content='mixed'>
  <attribute type='studentID'/>
  <element type='name'/>
  <element type='GPA'/>
</ElementType>

This process is continued throughout the rest of the schema until every element and attribute has been declared.

Unlike DTDs, XML Schemas allow you to have an open content model, allowing you to do such things as type elements and apply default values without necessarily restricting content.

In the following schema, the <GPA> element is typed and has an attribute with a default value, but no other nodes are declared within the <student> element.

<Schema xmlns="urn:schemas-microsoft-com:xml-data"
  xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <AttributeType name="scale" default="4.0"/>
  <ElementType name="GPA" content="textOnly" dt:type="float">
    <attribute type="scale"/>
  </ElementType>
  <AttributeType name="studentID"/>
  <ElementType name="student" content="eltOnly" model="open" order="many">
    <attribute type="studentID"/>
    <element type="GPA"/>
  </ElementType>
</Schema>

The preceding schema allows you to validate only the area with which you are concerned. This gives you more control over the level of validation for your document and allows you to use some of the features provided by the schema without having to employ strict validation.

Try it!

Try authoring a schema for the following XML document.

<order>
  <customer>
    <name>Fidelma McGinn</name>
    <phone_number>425-655-3393</phone_number>
  </customer>
  <item>
    <number>5523918</number>
    <description>shovel</description>
    <price>39.99</price>
  </item>
  <date_of_purchase>1998-10-23</date_of_purchase>
  <date_of_delivery>1998-11-03</date_of_delivery>
</order>

After you have completed the schema, run it through the XML Validator.

MSDN® Online Downloads provides a set of XML sample files, including an XML document with an accompanying schema. Download these samples to work with the XML document and the schema. To test the validity of your XML against a schema, you can load the document through the XML Validator or simply view the XML file in the MIMETYPE Viewer.

The following are some considerations.

  • ElementType and AttributeType declarations must precede attribute and element content declarations that refer to these types. For example, in the preceding schema, the ElementType declaration for the <GPA> element must precede the ElementType declaration for the <student> element.
  • The default value of the order attribute depends on the value of the content attribute. When the content is set to "eltOnly," the order defaults to seq. When the content is set to "mixed," the order defaults to many. For more information about these default values, see the XML Schema Reference.

Other Resources Other Resources

XML Validator | XML and XSL Samples and Demos


Lesson 7: Using Data Types Within XML Documents

What is a data type within an XML document?

A data type within an XML document is a type that has been assigned to an element on the instance using the dt:dt attribute, or through an XML Schema, a formal definition of an XML document. In addition, data types can be declared as elements. The XML parser uses the data type information to validate the document.

Previously, XML element values were limited to a single type String, so developers who wanted to process XML documents had to spend time converting all values to a type within their own applications. Typing your XML data will let the parser take care of data type conversions. In addition, because values are assigned a particular data type, changes made to that value must conform to that data type. This provides you with a method for validating user input.

In addition to having a string value, each XML element can also have a typed value. For example, the following XML element can have both a value of "1970-09-30" and a typed value of "Wed Sep 30 00:00:00 PDT 1970."

<date>1970-09-30</date>

How do I type XML element values?

Consider the following XML document

<?xml version="1.0"?>
<weather xmlns="x-schema:weatherSchema.xml">
  <date>1970-09-30</date>
  <degrees>67.5</degrees>
</weather>

where "weatherSchema.xml" is the following file:

<Schema xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <ElementType name="date" content="textOnly" dt:type="date"/>
  <ElementType name="degrees" content="textOnly" dt:type="float"/>
  <ElementType name="weather" content="eltOnly">
    <element type="date"/>
    <element type="degrees"/>
  </ElementType>
</Schema>

The preceding schema is a formal definition assigning data types to the elements of the preceding XML document. The attribute xmlns is the XML keyword for a namespace declaration. The declaration 'xmlns:dt="urn:schemas-microsoft-com:datatypes"' assigns dt to the namespace "urn:schemas-microsoft-com:datatypes." Any type qualified with dt will be from the namespace "urn:schemas-microsoft-com:datatypes."

The schema and data type namespaces are declared at the beginning of the XML Schema so that the dt prefix can then be used to denote which type attributes hold data type designations.

<Schema xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <ElementType name="NUMBER" content="textOnly" dt:type="number"/>

Typing an element within the XML document

An element can also be typed through the dt attribute on the instance of the element. To do this, declare the data type namespace at the beginning of the XML document.

<NUMBERS xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <NUMBER dt:dt="number">44533</NUMBER>
</NUMBERS>

The dt prefix can now be used on the dt attribute to assign a data type to an instance of an element.

Data types as elements within the XML document

In addition to declaring data types on the instance of an element and in a schema, they can also be used as elements. Compare the following examples. The first declares data types on the instance of an element.

<shoes xmlns:dt="urn:schemas-microsoft-com:datatypes" id="f1121" sizes="mens"/>
<sizes id="mens">
  <size dt:dt="int">8</size>
  <size dt:dt="int">10</size>
  <size dt:dt="int">12</size>
</sizes>

The second example declares the types as elements.

<shoes xmlns:dt="urn:schemas-microsoft-com:datatypes" id="f1121" sizes="array1"/>
<array id="array1">
  <dt:int>8</dt:int>
  <dt:int>10</dt:int>
  <dt:int>12</dt:int>
</array>

It is not possible to type such elements through schema.

For a list of data types that you can use in your XML documents, see XDR Data Types Reference.

Try it!

In the following text box, write an ElementType declaration for a <PRICE> element that has a data type of "fixed.14.4." Note that XML is case sensitive.


Lesson 8: Accessing Typed XML Values

What is a typed XML value?

A typed XML value is an XML element value that has been assigned a data type in an XML Schema, a formal definition of an XML document. The XML parser uses the schema to validate the document. The XML Schema information resides either in a schema file or within the XML document itself.

How do I access typed XML values?

It is possible to access typed data through the XML object model. Just as you can retrieve the value of an element by calling the nodeValue property on that element's node, you can retrieve the typed value of an element by calling the nodeTypedValue property on the element itself.

For example, consider the following XML document:

<?xml version="1.0"?>
<weather xmlns="x-schema:weatherSchema.xml">
  <date>1970-09-30</date>
  <degrees>67.5</degrees>
</weather>

where "weatherSchema.xml" is the following file:

<Schema xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <ElementType name="date" content="textOnly" dt:type="date"/>
  <ElementType name="degrees" content="textOnly" dt:type="float"/>
  <ElementType name="weather" content="eltOnly"/>
    <element type="date"/>
    <element type="degrees"/>
  </ElementType>
</Schema>

If you navigate to the <degrees> element (xmlDocument.documentElement.childNodes.item(1)), you can access its typed value by calling nodeTypedValue as follows: xmlDocument.documentElement.childNodes.item(1).nodeTypedValue.

Try it!

In the following text box, enter the code that will access the typed value of the <date> element. Assume that "xmlDocument" is the document object. Click the Check Code button.

To experience the validation capability of data types, see what happens when you enter a date that is not valid. In the following text box, enter an invalid date using the yyyy-mm-dd format. For example, enter "1998-13-02", and then click the Check Date Validation button.


Lesson 9: Using the C++ XML Data Source Object

What is the C++ XML Data Source Object?

Microsoft® Internet Explorer 5.0 and later is released with a C++ Data Source Object (DSO) that can be used to bind XML to HTML. Microsoft Internet Explorer 4.0 were released with a Java XML DSO that is still supported in Internet Explorer 5.0 and later; however, the new C++ DSO gives you better performance and the ability to bind directly to an XML data island.

The C++ DSO allows you to create XML-driven Web applications in a completely declarative fashion, although it is still possible to write scripts against the XML document object. With the C++ DSO, both the Microsoft ActiveX® Data Objects (ADO) and XML object models are available to you.

How do I bind XML to HTML?

Consider the following XML file.

<universities>
  <university>
    <name>UCSB</name>
    <location>Santa Barbara, CA</location>
  </university>
  <university>
    <name>University of Texas at Arlington</name>
    <location>Arlington, TX</location>
  </university>
  <university>
    <name>USM</name>
    <location>Hattiesburg, MS</location>
  </university>
  <university>
    <name>Baylor</name>
    <location>Waco, TX</location>
  </university>
</universities>

You can bind this XML to a repeating table with the following HTML.

<XML ID=xmlDoc src="universities.xml"></XML>
<TABLE DATASRC="#xmlDoc" BORDER=1>
  <THEAD><TH>NAME</TH><TH>LOCATION</TH></THEAD>
  <TR>
    <TD><SPAN DATAFLD="name"></SPAN></TD>
    <TD><SPAN DATAFLD="location"></SPAN></TD>
  </TR>
</TABLE>

Click the button below to view the table created.

UCSB Santa Barbara, CA University of Texas at Arlington Arlington, TX USM Hattiesburg, MS Baylor Waco, TX
NAME | LOCATION

There is no need for an <APPLET> or <OBJECT> tag; the XML DSO does all the work for you.

Try it!

For more information, see the XML Data Source Object demo in MSDN® Online Downloads. Download the sources for that demo and see if you can change the display format from a form to a repeated table.

Other Resources Other Resources

XML Data Source Object demo


Lesson 10: Using the Master/Detail Feature with the C++ XML Data Source Object

What is the master/detail feature?

The new master/detail feature allows you to bind to the current record of a hierarchical record set. This means that you can now bind the child elements of the current record to a distinct table. For example, consider the following XML.

<orders>
  <order order_number="2233">
    <customer>
      <name>John Smith</name>
      <custID>192883</custID>
    </customer>
    <item>
      <name>Fly Swatter</name>
      <price>9.99</price>
    </item>
  </order>
  <order order_number="2234">
    <customer>
      <name>Marea Angela Castaneda</name>
      <custID>827145</custID>
    </customer>
    <item>
      <name>Fly Paper</name>
      <price>15.99</price>
    </item>
  </order>
  <order order_number="2235">
    <customer>
      <name>Amy Jones</name>
      <custID>998022</custID>
    </customer>
    <item>
      <name>Mosquito Netting</name>
      <price>38.99</price>
    </item>
  </order>
</orders>

You can allow your user to navigate through the orders by ID, displaying only the customer and item information for the current order. Your user would not have to view the information for all orders — only for the one in which he or she is interested.

How do I bind to the details?

The key to binding to lower levels in the hierarchy (the details) is to understand the structure of your data. The preceding XML has three elements within the root (<orders>) element. Based on the heuristic employed by the XML Data Source Object (DSO), each order will be mapped to a rowset containing an "order_number", "customer", and "item" field. The "order_number" column will contain the value of the "order_number" attribute. The "customer" and "item" columns will contain pointers to respective "customer" and "item" recordsets. The "customer" recordset will then contain a "name" and "custID" field with the values of those elements within. The "item" recordset will contain a "name" and "price" field with the values of those elements within.

So, with this in mind, note that within the top-level (the "orders") recordset, you can get to the value of the "order_number." You will then allow your user to navigate through the orders by "order_number."

<P>ORDER NUMBER: <SPAN DATASRC="#xmlDoc" DATAFLD="order_number"></SPAN></P>

Now add some buttons to help users move throughout the "orders" recordset.

<INPUT TYPE=BUTTON VALUE="Previous Order" onclick="xmlDoc.recordset.movePrevious()">
<INPUT TYPE=BUTTON VALUE="Next Order" onclick="xmlDoc.recordset.moveNext()">

To retrieve the values within the child elements of the current record, create a table and set that table's DATASRC attribute to "#xmlDoc," exactly as was done in the preceding example. However, this time also set its DATAFLD attribute to "customer." This tells the table to bind to data within the "customer" recordset pointed at within the "customer" field of the "orders" recordset.

<TABLE DATASRC="#xmlDoc" DATAFLD="customer" BORDER>
  <THEAD><TH>NAME</TH><TH>ID</TH></THEAD>
  <TR>
    <TD><SPAN DATAFLD="name"></SPAN></TD>
    <TD><SPAN DATAFLD="custID"></SPAN></TD>
  </TR>
</TABLE>

Then do the same for the data within the "item" element.

<TABLE DATASRC="#xmlDoc" DATAFLD="item" BORDER=1>
  <THEAD><TR><TH>ITEM</TH><TH>PRICE</TH></TR></THEAD>
  <TR>
    <TD><SPAN DATAFLD="name"></SPAN></TD>
    <TD><SPAN DATAFLD="price"></SPAN></TD>
  </TR>
</TABLE>

Now, as the user clicks the buttons and moves to the next and previous records in the recordset, the data in the tables will change to correspond to the current record.

Click the Show Example button to view the page created above.

John Smith 192883 Fly Swatter 9.99 Candice Calloway 827145 Fly Paper 15.99 Mandy Jones 998022 Mosquito Netting 38.99

ORDER NUMBER:

NAME | ID
ITEM | PRICE

Try it!

See if you can use the preceding XML to create a Web page that will allow a user to navigate through the orders by customer name.


Using XML on the Server

The XML engine included in Microsoft® Internet Explorer 5.0 and later can also be used on the server. This allows data-rich Web applications in which XML data can be created, manipulated, and transmitted between client and server.

The following topics provide an introduction to the use of the Internet Explorer 5.0 XML engine on the server.

  • Instantiating the XML Control
  • Choosing a Threading Model
  • Getting the XML Data
  • Sending XML Between the Client and Server
  • Saving XML
  • Converting XML to HTML


Instantiating the XML Control

Installing Microsoft® Internet Explorer 5.0 and later on the server installs the msxml.dll, which contains all the components of the XML engine, including the Microsoft XML Parser (MSXML), the Extensible Stylesheet Language (XSL) processor, schema support, and so on.

Instantiate the XML control the way you would any other control on the server. For example, from an Active Server Pages (ASP) page you would use code like the following.

var xObj = Server.CreateObject("msxml2.DOMDocument");

Alternatively, a server-side object can be used.

<OBJECT RUNAT="server" PROGID="msxml2.DOMDocument" id="xObj"> </OBJECT>

The "xObj" is an empty IXMLDOMDocument/DOMDocument object, ready to build in memory or load from an XML file or XML stream.


Choosing a Threading Model

There are two versions of the XML control.

rental model
The rental model version is designed for single-threaded access. To use the rental model control, use the "Microsoft.DOMDocument" progID.
free-threaded model
The free-threaded version is designed for multiple thread access. To use the free-threaded control, use the "Microsoft.FreeThreadedDOMDocument" progID.

If you plan for several threads to access your XML data from a single control, be sure to use the free-threaded control. If only one thread will access the XML data, use the rental model control for better performance.

The following is a sample global.asa file that creates session-level and application-level free-threaded versions of the XML control.

<SCRIPT LANGUAGE=VBScript RUNAT=Server>
  Sub Session_OnStart
    ON error RESUME next

    SET Application("AppFXMLdoc") = _
      server.CreateObject("MSXML2.FreeThreadedDOMDocument")
    SET Session("SessFXMLdoc") = _
      server.CreateObject("MSXML2.FreeThreadedDOMDocument")
  End Sub
  Sub Session_OnEnd
    ON error RESUME next

    SET Session("SessFXMLdoc") = nothing
    SET Application("AppFXMLdoc") = nothing
    Session("SessFXMLdoc") = empty
    Application("AppFXMLdoc") = empty
  End Sub
</SCRIPT>

Scripts accessing the Session and Application objects will be able to simultaneously access the "AppFXMLdoc" and "SessFXMLdoc" objects.


Getting the XML Data

The following are ways to get XML data on the server.

  • Use Microsoft® ActiveX® Data Objects (ADO) 2.1 or later to get XML information directly from any database that supports ADO.
  • Read data from a database or other source and construct an XML tree using the Document Object Model (DOM).
  • Load an XML file using the XML control's load method.
  • Construct a string and load it into the XML control using the loadXML method.
  • Construct an XML text string directly, without building an XML document object on the server.

Some of these methods are illustrated in the following sections.

Constructing an XML Tree Using the DOM

The XML DOM provides the ability to programmatically construct an XML document from data read from a database or other data source.

The following code reads data from a database and constructs an XML document using the DOM. The document is then sent to the client as an XML text stream.

<% Response.ContentType = "text/xml" %>
<?xml version="1.0" encoding="windows-1252" ?>
<%
' Check to see if a document has data. If it does, don't build it
if (xmldoc.childNodes.length = 0) then
  ' Build the XML document
  set root = xmldoc.createNode("element","SalesData","")
  xmldoc.appendChild(root)
  ' Queries the database for customer data
  SQL = "SELECT OrderID, CompanyName, OrderDate, ShippedDate, " & _
        "       ShipCity, ShipState " & _
        " FROM Customers " & _
        "INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID "
  set Conn = Server.CreateObject("ADODB.Connection")
  Conn.Open("pdc")
  set rs = Conn.Execute(SQL)
  ocount = 0
  rs.MoveFirst()
  while (not rs.EOF and ocount < 10)
    set onode = xmldoc.createNode("element","Order","")
    xmldoc.documentElement.appendChild(onode)
    for i = 0 to rs.Fields.Count - 1
      set child = xmldoc.createNode("element",rs.Fields(i).Name,"")
      child.text = rs.Fields(i)
      onode.appendChild(child)
    next
    pcount = 0
    set isnode = xmldoc.createNode("element","Items","")
    onode.appendChild(isnode)
    iSQL = "select ProductName, OrderDetails.UnitPrice as UnitPrice," & _
           "       Quantity from OrderDetails" & _
           " inner join Products on Products.ProductID = OrderDetails.ProductID" & _
           " where OrderID = "
    iSQL = iSQL & rs("OrderID")
    set irs = Conn.Execute(iSQL)
    irs.MoveFirst()
    while (not irs.EOF and pcount < 3)
      set inode = xmldoc.createNode("element","Item","")
      isnode.appendChild(inode)
      for i = 0 to irs.Fields.Count - 1
        set child = xmldoc.createNode("element",irs.Fields(i).Name,"")
        child.text = irs.Fields(i)
        inode.appendChild(child)
      next
      irs.MoveNext()
      pcount = pcount + 1
    wend
    rs.MoveNext()
    ocount = ocount + 1
  wend
end if
Response.Write(xmldoc.xml)
%>

The DOM methods createNode and appendChild and the text property are used to construct the XML tree. The xml property writes the document out as an XML stream, which is then sent to the client.

Loading XML from a File

The DOM load method can be used to build a DOM document from a URL.

xObj = Server.CreateObject("msxml2.DOMDocument");
xObj.load(Server.MapPath("simple.xml"));

The MapPath method resolves the relative path to a full path.

Directly Constructing XML Text

If you do not need to process or cache the XML on the server, you can choose to simply construct the XML text without using the XML control. This does not require the XML control to be installed on the server.

The following example reads data from a database and injects it into the output stream.

<% Response.ContentType = "text/xml" %>
<?xml version="1.0" encoding="windows-1252" ?>
<SalesData>
<%
SQL = "SELECT OrderID, CompanyName, OrderDate, ShippedDate, " & _
      "       ShipCity, ShipState " & _
      " FROM Customers " & _
      "INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID " & _
      "ORDER BY ShipState"
set Conn = Server.CreateObject("ADODB.Connection")
set rs = Server.CreateObject("ADODB.Recordset")
Conn.Open("pdc")
set rs = Conn.Execute(SQL)
rs.MoveFirst()
while (not rs.EOF)
%>
  <Order>
    <OrderID> <%= rs("OrderID") %> </OrderID>
    <Customer> <%= rs("CompanyName") %> </Customer>
    <OrderDate> <%= rs("OrderDate") %> </OrderDate>
    <ShippedDate> <%= rs("ShippedDate") %> </ShippedDate>
    <ShipCity> <%= rs("ShipCity") %> </ShipCity>
    <ShipState> <%= rs("ShipState") %> </ShipState>
  </Order>
<%
    rs.MoveNext()
wend
rs.close()
conn.close()
%>
</SalesData>

Because the XML tags are generated directly as text, the overhead of building the DOM document object is avoided.


Sending XML Between the Client and Server

When sending XML to the client, you must first create a textual version of the XML.

To create the textual version, you can use the xml property of the root node of the XML document, as shown in the following fragment.

Response.Write(xObj.xml);

You can also use the technique described in Getting the XML Data.

After you have the XML text string, you can use one of the following approaches to send it to the client in response to a client request.

  • Maintain the XML as a file on the server. The client can load this file directly using the load method, as shown in the following.
    xObj.load("http://www.microsoft.com/sample.xml");
  • Create and return the XML from an Active Server Pages (ASP) page. The client can load the result using the load method, as shown in the following.
    xObj.load("http://www.microsoft.com/sample.asp");
  • Create and return XML information in response to a request from the XMLHTTP control.

Getting XML Back from the Client

You can send XML to the server using any standard technique for sending information to the server.

  • Post information from a form.
  • Post information from a form in a hidden frame.
  • Use the XMLHTTP control to send and receive XML information using HTTP requests.

For more information about posting data, see the DHTML documentation.


Saving XML

You can save XML on the server using the save method, as shown in the following excerpt.

<%
  Response.Expires = -1000;
  if (Request.ServerVariables("REQUEST_METHOD") == "POST")
  {
    // Load the posted XML data and save it to disk.
    xmldoc.load(Request);
    xmldoc.save(Server.MapPath("saved.xml"));
%>
Ok
<%
  }
%>

The MapPath method resolves relative paths into the full paths required on the server.


Converting XML to HTML

If you want to maintain XML information on the server and format it as HTML to send to the client, you can use any server-side technique, such as from script in an Active Server Pages (ASP) page. In addition, you can use Extensible Stylesheet Language Transformations (XSLT) to format the information.

If the client is Microsoft® Internet Explorer 5.0 or later, you can send an XML file with an embedded XSLT reference, and the browser will automatically format the sent XML using the referenced style sheet. For more information, see Displaying XML Files in a Browser.

See Also

Serving Out XML Files from an HTTP Server | Using XSLT within ASP


XML and Security

Making XML documents secure requires secure infrastructures for transferring and processing those documents. On the client side, security zones in Microsoft® Internet Explorer 5.0 and later can help you manage the flow of XML information. On the server side, you must create applications that manage security, not just for XML documents, but for all the resources, including external entities, document type definitions (DTDs), and style sheets, referenced by those XML documents.

  • XML Client Security
  • XML Server Security


XML Client Security

This topic describes how you can use the Microsoft® XML Parser (MSXML) and the security zones of Microsoft Internet Explorer 5.0 and later.

Accessing Data Across Domains

The security scheme for MSXML is based on Internet Explorer security zones and settings. The Access data sources across domains setting allows the user three options: Disable, Enable, or Prompt. The following are the four security zones and their defaults for the Access data sources across domains setting.

Internet
Disable
Local intranet
Prompt
Trusted
Enable
Restricted
Disable

If a user loads a page in the Local intranet zone that uses MSXML to access data from another site in the Local intranet zone, the user will be prompted that data is being accessed across domains.

Accessing Data Across Protocols

Access is denied if either of the following cross-protocol access is attempted:

  • https to http access
  • http to https access

Accessing Data Across Zones

Cross-zone access of data is permitted only in cases in which more trusted zones access data from less trusted zones. This allows intranet applications to access data on the intranet and Internet.

The following table describes which zones have access to other zones when the Access data sources across domains setting is set to Enable or Prompt.

 | To Zone |  |  |  |
From Zone | Local | Internet | Local Intranet | Trusted Sites | Restricted Sites
Local | Access Granted | Access Granted | Access Granted | Access Granted | Access Denied
Internet | Access Denied | Access Granted | Access Denied | Access Denied | Access Denied
Local Intranet | Access Denied | Access Granted | Access Granted | Access Denied | Access Denied
Trusted Sites | Access Denied | Access Granted | Access Granted | Access Granted | Access Denied
Restricted Sites | Access Denied | Access Denied | Access Denied | Access Denied | Access Denied

Note Although Local is not one of the four security zones, the parser treats files on the local computer as if they are in their own zone.


XML Server Security

During processing, XML files can rely on XML schemas, document type definitions (DTDs), external entity files, and style sheets. The contents of these supporting files can affect the content and presentation of the XML documents and must receive the same level of security protection as the XML files themselves.

XML files and their supporting files can be managed using conventional permissions and authentication strategies. Information entering or leaving a database through an XML file can be managed with both database security and security on the XML conversion mechanisms. For the most part, these issues are handled in the same way they are for HTML files and databases that store information for distribution over the Web.

In some cases, developers rely on supporting files from sources they do not control. For example, the Worldwide Web Consortium (W3C) hosts the DTDs for XHTML, the XML version of HTML. Consortia sites and schema repositories provide many sources of ready-to-use XML document structures and supporting files. Developers should check that the hosting organization is providing adequate security and that the files cannot be modified without permission.


XML Data Islands

There is an increasing need to be able to embed "islands" of data inside HTML pages. In Microsoft® Internet Explorer 5.0 and later, these data islands can be written in XML.

The following topics describe the syntax used for embedding these data islands within a page, and detail the object model exposed by the browser to enable them to be used. This method of embedding XML in HTML follows the note published by the Worldwide Web Consortium (W3C) as the "XML in HTML Meeting Report." The W3C expects to evolve the HTML specification to include the capability of embedding XML in HTML documents.

Embedding an XML Data Island into an HTML Page

An XML data island can be embedded using one of the following methods.

  • Using the Dynamic HTML (DHTML) XML element within the HTML document
  • Overloading the HTML SCRIPT element

Using the XML Element Within the HTML Document

This syntax is valid for Internet Explorer 5.0.

There are two syntactically correct ways of using the XML element within the HTML document.

  • The XML data can exist inline, surrounded by XML start and end tags.
    <XML ID="XMLID">
  <XMLDATA>
    <DATA>TEXT</DATA>
  </XMLDATA>
</XML>
  • The XML element can have a SRC attribute, the value of which is the URL for an XML data source.
    <XML SRC="http://localhost/xmlFile.xml"></XML>

The XML element is present in the HTML Document Object Model. It is in the DHTML all collection and is seen by the browser as just a regular node. The XML data within the XML element can then be accessed by calling the DHTML XMLDocument property on the XML element.

The XMLDocument property returns the root node of the XML within the XML element or the root node of the XML referenced by the value of the SRC attribute. From this root, the XML data island can be navigated using the XML Document Object Model (DOM). The following function returns the data from the data island with the ID of "XMLID".

function returnXMLData(){
  return document.all("XMLID").XMLDocument.nodeValue;
  }

The XML element can also be referenced by ID alone. For example, the following function has the identical functionality as the preceding example.

function returnXMLData(){
  return XMLID.documentElement.text;
  }

Because the XMLDocument property was not used, the documentElement property must be called to retrieve the root element of the XML.

Overloading the HTML SCRIPT Element

This syntax has been deprecated and is intended only for down-level cases.

There are three syntactically correct ways of overloading the DHTML SCRIPT element.

  • The LANGUAGE attribute can be given the value "XML".
    <SCRIPT LANGUAGE="XML">
  • The TYPE attribute can be given the value "text/xml".
    <SCRIPT TYPE="text/xml">
  • As with the XML element, a SRC attribute can be added, the value of which is the URL for an XML data source.
    <SCRIPT LANGUAGE="XML" SRC="http://localhost/xmlFile.xml"></SCRIPT>

The following HTML fragment illustrates how to embed data by overloading the SCRIPT element.

<SCRIPT ID="XMLID" LANGUAGE="XML">
  <XMLDATA>
    <DATA>TEXT</DATA>
  </XMLDATA>
</SCRIPT>

The SCRIPT element is present in the HTML page's object model. (It is in the DHTML all collection and is seen by the browser as a regular script node.) The XML data within the SCRIPT elements can be accessed by calling the XMLDocument property on the SCRIPT object.

The following script accesses the XML data island in the preceding HTML fragment and returns the name of the root node of the XML data island.

function returnIslandRootName(){
  var islandRoot = document.all.("SCRIPT").XMLDocument;
  return islandRoot.nodeName;
  }
Note A tag that uses the name "XML" cannot be nested within an XML data island.


Binding the XML Data Source Object to Data

The XML Data Source Object (DSO) allows you to bind HTML elements to an XML data set. By doing so, you can display a table of elements and attributes contained in the XML data. The contents of the table will change as the XML data changes.

The following topics show how you can use the XML DSO for data binding.

  • Data Islands
  • Using the XML Data Source Object
  • Additional Data Binding and XML Resources


Data Islands

In Microsoft® Internet Explorer 5.0, you can the use XML element to create a data island. Data islands are XML data referenced or included in an HTML page. The XML data can be included within the HTML or it can be in an external file.

Using the XML element allows you to avoid using script; if the user has disabled scripting for security reasons, the object tag version will not work because script is required to initialize the XML.

Inline XML

Inline XML is enclosed within the <XML> and </XML> tags, as shown in the following example.

<XML ID="xmlData">
<?xml version="1.0" ?>
<trees>
<tree>
<name>Birch</name>
<height unit="foot">10</height>
</tree>
<tree>
<name>Aspen</name>
<height unit="foot">4</height>
</tree>
</trees>
</XML>

References to XML Files

External XML uses the SRC attribute on the <XML> tag to reference an external file. The SRC attribute can refer to a local file or specify a URL. By using URLs that point to external servers, data can be integrated from several sources. The following code uses the SRC attribute with a local file.

<XML ID="xmlData" SRC="xmlData.xml"></XML>

The file "xmlData.xml" contains the XML. The SRC attribute can refer to a URL as well, as in the following example.

<XML ID="xmlData" SRC="http://msdn.microsoft.com/workshop/author/composer.xml">
</XML>

Reading Data from Within a Data Island

The ID attribute given with the <XML> tag is used to reference the data island. By using HTML tags that can accept data source tags (binding the HTML to the data), you can format and display the data in the XML data island. The following example displays the XML items tagged with <meeting>.

<HTML><HEAD></HEAD><TITLE></TITLE>
<BODY>
<XML ID="xmlMeetings">
<?xml version="1.0" ?>
<meetings>
<meeting>
<date>1/1/99</date>
<time>9:00</time>
<location>104</location>
</meeting>
<meeting>
<date>2/1/99</date>
<time>13:00</time>
<location>34</location>
</meeting>
<meeting>
<date>3/1/99</date>
<time>14:30</time>
<location>20</location>
</meeting>
</meetings>
</XML>
<table datasrc="#xmlMeetings">
<tr>
<td><div datafld="date"></div></td>
<td><div datafld="time"></div></td>
<td><div datafld="location"></div></td>
</tr>
</table>
</BODY>
</HTML>

The <table> tag uses the DATASRC attribute to reference the inline XML. The DATASRC refers to the ID attribute used to identify the XML preceded by a pound sign (#). The TD element cannot be bound to data, so a tag that binds to data must be used. In this case, it is the DIV element. The DIV element also allows the DATAFLD attribute to refer to the XML element to place in this cell of the table. In this case, it is DATAFLD="date" for the <date> XML element.

As the XML is read, additional rows are created for each element tagged with the <meeting> tag.


Using the XML Data Source Object

You can either use the OBJECT element to refer to the XML data source object, or you can use data islands and the XML element.

The XML data source Microsoft® ActiveX® object can be inserted into an HTML page as follows.

<OBJECT width=0 height=0
    classid="clsid:550dda30-0541-11d2-9ca9-0060b0ec3d39"
    id="xmldso">
</OBJECT>

This can be used as an XML data provider in conjunction with the data binding features of Microsoft Internet Explorer 5.0 for binding XML data to HTML elements on the page.

To load XML into the data source object, use the Dynamic HTML (DHTML) XMLDocument property to get a Document Object Model (DOM), and then call the load method as follows.

<SCRIPT for=window event=onload>
    var doc = xmldso.XMLDocument;
    doc.load("books.xml");
    if (doc.documentNode == null)
    {
        HandleError(doc);
    }
</SCRIPT>

Inline XML

You can also provide the XML inline inside the OBJECT element, as shown in the following example.

<OBJECT width=0 height=0
    classid="clsid:550dda30-0541-11d2-9ca9-0060b0ec3d39"
    id="xmldso">
<favorites>
<favorite>
<name>Microsoft</name>
<url>http://www.microsoft.com</url>
</favorite>
</favorites>
</OBJECT>

You use script to load the data source object as follows.

<SCRIPT for=window event=onload>
    var doc = xmldso.XMLDocument;
    doc.loadXML(xmldso.altHtml);
    if (doc.documentNode == null)
    {
        HandleError(doc);
    }
</SCRIPT>

Events Used with the XML Data Source Object

The XML data source object triggers events when the underlying XML data changes. These events are common among the XML data source object and the other supplied data source objects. For more information about events and the data source object, see DHTML Event Model Support for Data Binding in the DHTML documentation.

Viewing and Navigating a Subset of the Data

If you want a table to display a small portion of your XML data set, use the DATAPAGESIZE attribute on your TABLE element. The DATAPAGESIZE attribute indicates how many records to display in the table.

To navigate the table, you can use the nextPage, previousPage, firstPage, and lastPage methods to display different pages of the data.

Usually, you can provide buttons to view different pages of the data set with nextPage, previousPage, firstPage, and lastPage. For example, a button to view the next page can be written as follows.

<INPUT TYPE="button" VALUE="Next" ONCLICK="tbl.nextPage();">

To specify the table, you can use the following code.

<TABLE DATAPAGESIZE=1 ID=tbl DATASRC=#xmlData>
...Table...
</TABLE>

This example sets the table to display one record (DATAPAGESIZE=1), identifies itself as "tbl" (ID=tbl), and uses a data source called "xmlData".

To indicate which table the button refers to, use the ID attribute used with the TABLE element.

The ONCLICK attribute can also specify "previousPage", "firstPage", or "lastPage". For example, to create a button to display the first page, use the following.

<INPUT TYPE="button" VALUE="First Page" ONCLICK="tbl.firstPage();">

The $Text Data Field

When you bind data using the XML data source object, an automatic field called "$Text" is created. It contains the items in that record, concatenated. The following example demonstrates the $Text data field.

<HTML><HEAD></HEAD><TITLE></TITLE>
<BODY>
<XML ID="xmlParts">
<?xml version="1.0" ?>
<parts>
<part>
<partnumber>A1000</partnumber>
<description>Flat washer</description>
<quantity>1000</quantity>
</part>
<part>
<partnumber>S2300</partnumber>
<description>Machine screw</description>
<quantity>1000</quantity>
</part>
<part>
<partnumber>M2400</partnumber>
<description>Nail</description>
<quantity>500</quantity>
</part>
</parts>
</XML>
<table datasrc=#xmlParts>
<tr>
<td><div datafld="partnumber"></div></td>
<td><div datafld="$Text"></div></td>
</tr>
</table>
</BODY>
</HTML>

In this example, the table will consist of a column of part numbers (where datafld is equal to "partnumber") and a column containing the part number, description, and quantity concatenated (where datafld is equal to "$Text"). For example, the first row of the partnumber column will contain "S2300", while the second row of the $Text column will contain "S2300 Machine screw 1000". The $Text column contains the part number.

Rules for Assigning XML Elements and Attributes to Columns and Rows

The XML data source object follows a procedure for assigning elements and attributes to columns and rows in databound applications. XML is modeled as a tree with one tag containing the entire hierarchy. For example, an XML description of a book can contain chapter tags, figure tags, and section tags. A book tag can contain the subelements of chapter, figure, and section. When the XML data source object assigns rows and columns, the subelements, not the top level element, are converted.

The XML data source object uses this procedure for converting the subelements.

Each subelement and attribute corresponds to a column in some rowset in the hierarchy.

The name of the column is the same as the name of the subelement or attribute, unless the parent element has an attribute and a subelement with the same name, in which case a "!" is prepended to the sublement's column name.

Each column is either a simple column containing scalar values, usually strings, or a rowset column containing subrowsets.

Columns corresponding to attributes are always simple.

Columns corresponding to subelements are rowset columns if either the subelement has its own subelements and/or attributes, or the subelement's parent has more than one instance of the subelement as a child. Otherwise, the column is simple.

When there are multiple instances of a subelement (under different parents), its column is a rowset column if any of the instances imply a rowset column; its column is simple only if all instances imply a simple column.

All rowsets have an additional column named $Text.

A simpler conversion takes place if you have set the JavaDSOCompatible flag to True. The JavaDSOCompatible flag makes the Internet Explorer 5.0 XML data source object compatible with the Java data source object supplied with Internet Explorer 4.0. To set the JavaDSOCompatible flag, you can use the XML element as follows.

<xml id="xmldata" JavaDSOCompatible=true>
...XML data
</xml>

Or, you can use the following with the OBJECT element (using the XML element is recommended).

<OBJECT width=0 height=0
    classid="clsid:550dda30-0541-11d2-9ca9-0060b0ec3d39"
    id="xmldso">
<PARAM NAME="JavaDSOCompatible" value="true">
</OBJECT>

The following method is used for creating rows and columns when JavaDSOCompatible is True.

Any element that contains another element is automatically a rowset.

Elements that contain only text are columns.

Values stored in attributes are ignored.

For more information about the Java XML data source object, see XML Data Source in the DHTML documentation.

Using DTDs

If you use a document type definition (DTD) with your XML, the XML data source object uses the following method for converting elements and attributes to rows and columns.

Each subelement and attribute named by the DTD corresponds to a column in some rowset in the hierarchy.

The name of the column is the same as the name of the subelement or attribute, unless the parent element has an attribute and a subelement with the same name, in which case a "!" is prepended to the sublement's column name.

Each column is either a simple column containing scalar values, usually strings, or a rowset column containing subrowsets.

Columns corresponding to attributes are always simple.

Columns corresponding to subelements are rowset columns if either the DTD allows the subelement to have its own subelements and/or attributes, or the DTD allows the subelement's parent to have more than one instance of the subelement as a child. Otherwise the column is simple.

All rowsets have an additional column named $Text.

Content corresponding to the content model "ANY" is not included in the rowset hierarchy.


Additional Data Binding and XML Resources

For more information about data binding, see the following topics in the DHTML documentation.

  • Data Binding
  • Data Binding Architecture
  • Adding a Data Source Object to a Page
  • Binding HTML Elements to Data
  • DHTML Object Model Support for Data Binding
  • DHTML Event Model Support for Data Binding

For tutorials and demos, see the following resources.

  • Lesson 9: Using the C++ XML Data Source Object
  • Lesson 10: Using the Master/Detail Feature with the C++ XML Data Source Object
  • XML Data Source Object sample on MSDN® Online. See XML And XSL Samples.


XML Samples You Can Download

[This is preliminary documentation and subject to change.]

You can use the following resources to download XML sample applications and demos.

Other Resources Other Resources

XML and XSL Samples and Demos on MSDN

Provides links to several sample applications that incorporate XML technologies as part of a larger solution. The XML and XSL Samples and Demos page also provides stand-alone samples and demos

MSDN Code Center

Provides a wide assortment of XML code samples and related documentation.


(Deprecated) Push Model XML Parser/Node Factory

[Deprecated. Do not use. Superseded by SAX2 API/MSXML 3.0]

This section describes an obsolete, proprietary, low-level interface for manipulating XML without building an in-memory tree representation of the entire XML document. It was intended to be a high performance XML parser, but has been completely superceded by the industry standard Simple API for XML (SAX2) application programming interface (API) that is available in the Microsoft® XML Parser (MSXML) 3.0. It is highly recommended to use SAX2 API instead of NodeFactory interface. NodeFactory interface is deprecated and provided strictly "as is." No changes will be made to it; no support will be provided; and no future upgrades will be available.


Introduction

[Deprecated. Do not use. Superseded by SAX2 API/MSXML 3.0]

This interface was designed in lieu of an industry standard application programming interface (API) for customers who want to scan a chunk of XML to find a certain tag. For example, the Channel Definition Format (CDF) viewer must scan every CDF file in a folder for a LOGO tag that has an ICON attribute so it can display the appropriate icon.

The Push Model XML Parser consists of low-level interfaces that are designed for C programmers only. The Push Model XML Parser includes an IXMLParser interface that is used to parse XML either from an IStream, or directly from an in-memory buffer or a URL. The parser also includes a Node Factory callback interface, which the parser calls for each XML tag or attribute it finds in the source. The client implements its own Node Factory.

Alternatives

The Node Factory is not the best way for applications to deal with XML. The Node Factory has been replaced by the Simple API for XML (SAX2) API in the Microsoft® XML Parser (MSXML) 3.0. The Document Object Model (DOM) is another supported industry standard API available in this version of MSXML. The IXMLDOMNode interface maintains an in-memory tree representation of an XML document and provides methods for navigating, updating, querying, and transforming the tree. The DOM also provides other features like document type definition (DTD) validation, XML Schema, and DataType support.


(Deprecated) IXMLParser Interface

[Deprecated. Do not use. Superseded by SAX2 API/MSXML 3.0]

The parser takes XML input in a variety of ways (for example, through a stream, a URL to a document, or text pushed to it), parses the XML, and sends parse events to a NodeFactory. The parser is divided into two interfaces. An IXMLNodeSource interface defines the parse events and other information, such as position information for parse errors that are sent to a NodeFactory. The IXMLParser interface inherits from IXMLNodeSource, and adds methods to define the XML source (stream, URL, or pushed text), set NodeFactories, and deal with security and state reporting issues.

interface IXMLParser : IXMLNodeSource
{
    HRESULT SetURL(
        [in] const WCHAR* pszBaseUrl,
        [in] const WCHAR* pszRelativeUrl,
        [in] BOOL fAsync);

    HRESULT Load(
        [in] BOOL fFullyAvailable,
        [in] IMoniker *pimkName,
        [in] LPBC pibc,
        [in] DWORD grfMode);

    HRESULT SetInput(
        [in] IUnknown *pStm);

    HRESULT PushData(
        [in] const char* pData,
        [in] ULONG ulChars,
        [in] BOOL fLastBuffer);

    HRESULT LoadDTD(
        [in] const WCHAR* pszBaseUrl,
        [in] const WCHAR* pszRelativeUrl);

    HRESULT LoadEntity(
        [in] const WCHAR* pszBaseUrl,
        [in] const WCHAR* pszRelativeUrl,
        [in] BOOL fpe);

    HRESULT ParseEntity(
        [in] const WCHAR* pwcText,
        [in] ULONG ulLen,
        [in] BOOL fpe);

    HRESULT ExpandEntity(
        [in] const WCHAR* pwcText,
        [in] ULONG ulLen);

    HRESULT SetRoot(
        [in] PVOID pRoot);

    HRESULT GetRoot(
        [in] PVOID* ppRoot);

    HRESULT Run(
        [in] long lChars);

    HRESULT GetParserState();

    HRESULT Suspend();

    HRESULT Reset();

    HRESULT SetFlags(
        [in] ULONG iFlags);

    HRESULT SetSecureBaseURL(
        [in] const WCHAR* pszBaseUrl);

    HRESULT GetSecureBaseURL(
        [out] const WCHAR** ppwcBuf);
};

The parser is multithread safe, meaning it is safe to call these methods from any thread. They are protected by a critical section.

SetURL

The SetURL method is one of four different methods for providing input to the parser. The other methods are Load, SetInput, and PushData. You pass a base URL, and a relative URL. For example, if the base URL is http://www.microsoft.com/xml/test.htm and the relative URL is test.xml, the resulting file that will be loaded is http://www.microsoft.com/xml/test.htm.

Note This example shows how this method is useful when you have the base URL of an HTML page and you want to fetch an XML document relative to that without doing with any string manipulation. "test.htm" is arbitrary; it has nothing to do with the function of the XML parser.

The pszBaseURL is optional and is only there so that you do not have to resolve relative URLs yourself. Passing a full URL for the pszRelativeURL overrides the pszBaseURL, and the pszBaseURL can be NULL. You cannot pass a NULL for the pszRelativeURL. You can pass a directory as the base as long as there is a trailing "/", for example, http://www.microsoft.com/xml/.

File URLs have some additional behavior. The base URL file://central/, where central is the name of a server, is not valid. You must also specify the name of the "share" on that server, for example: file://central/public/. Relative file URLs without a base URL load the file from the "current directory" for that process.

The async flag controls whether an HTTP request is handled synchronously or asynchronously. If it is async, you will get E_PENDING from Run and you must pump your message queue. When data becomes available, the parser will be notified by URLMON (through the message queue) and will parse the new data and your NodeFactory will continue to be called.

Load

The Load method corresponds to the load method in IPersistMoniker. The parser will call BindToStorage to get an IStream and load the XML associated with the given moniker. You can also call GetURL to get the URL representation of the given moniker. This method will not work on a moniker created by CreateFileMoniker. Use CreateURLMoniker instead.

SetInput

Use the SetInput method if you already have an IStream containing XML. If the stream returns E_PENDING, then the parser returns E_PENDING from Run(). The caller then must call Run again when more data is available.

PushData

The lowest level way to provide input is as a raw buffer of bytes. The buffer is not NULL terminated. You call the PushData method with each buffer. Run() will continue to return E_PENDING until you call PushData with the lastBuffer argument set to TRUE. An XML token can span multiple buffers. For example, the first buffer might end with "<!-- foo", in which case the parser will return E_PENDING; if the next buffer starts with "bar--->", the parser will complete the token and call the NodeFactory with the combined COMMENT text "<!---foobar--->".

When you call PushData with lastBuffer set to TRUE, you should not push any more data unless you first reset the parser. If you do, the behavior is undefined.

LoadDTD

After you have started parsing XML, you may want to fetch an external document type definition (DTD). For example, if the XML document contains <!DOCTYPE foo SYSTEM "somedtd.dtd">, you can load that DTD by calling LoadDTD on the parser. Your factory will then be called to handle all the DTD nodes, just as it does for a DTD internal subset.

LoadEntity

DTDs can define external entities <!ENTITY bar SYSTEM "ent.xml">. The LoadEntity method is used to go fetch those entities. The fpe argument specified that this is a parameter entity.

ParseEntity

The ParseEntity method is used to parse the value of an internal entity reference <!ENTITY bar "<x>internal</x>">. CreateNode calls will be made for the contents of the entity.

ExpandEntity

The ExpandEntity method is used to expand an entity reference. For example, when a parameter entity is used in a DTD, %foo; this method can be called to provide the entity replacement text that the parser should insert into the input stream before continuing to parse.

SetRoot, GetRoot

The SetRoot method provides the pNodeParent argument for all root level CreateNode calls. Because you must manage any reference counting that may be required on this object, you may have to use the GetRoot method after parsing.

Run

The Run method parses the specified amount of XML (in characters); it returns E_PENDING if it is not finished or S_OK when it reaches the end of the input. An amount of -1 means parse as much as it can get from the input stream. If you are using the PushData method, the Run method returns E_PENDING until you push the last buffer; after that, it will return S_OK. The number given to Run is just a hint. Run will still succeed even if the specified number of characters are not left in the input buffer.

If you started an asynchronous download, Run(-1) will return E_PENDING; as long as your application has a message loop, the download and parsing will occur in the background as data becomes available from URLMON. You can check GetParserState periodically; at some point the parser will no longer return XMLPARSER_BUSY. If you want to monitor the progress, you can use the Load method, register your own IbindStatusCallback, and watch the OnProgress calls.

GetParserState

GetParserState returns one of the following values indicating the state of the parser.

typedef enum
{
    XMLPARSER_IDLE,   // The parser is in the Reset state
    XMLPARSER_WAITING,   // The input stream returned E_PENDING
    XMLPARSER_BUSY,   // There is data available for parsing
    XMLPARSER_ERROR,   // The parser found an error
    XMLPARSER_STOPPED,   // Abort was called
    XMLPARSER_SUSPENDED,// Suspend was called
} XML_PARSER_STATE;

If the parser found an error, this takes precedence over subsequent calls to Abort() or Suspend(); you will still get XMLPARSER_ERROR in this case. Also, if you aborted the parser, this takes precedence over Suspend(); you will still get XMLPARSER_STOPPED even though the parser is also suspended.

Suspend

The parser can be suspended at any time; to resume parsing, call Run again. This helps clients tweak performance with just-in-time parsing.

Reset

The Reset method puts the parser back into the initial state so you can load another XML file. Reset also resets the root object, the root NodeFactory, and all other Node Factories that may be in the current parser context.

SetFlags

SetFlags is used for setting the flags defined in IXMLNodeSource::GetFlags.

SetSecureBaseURL,GetSecureBaseURL

The secure base URL is used to stop cross-domain data access. After the secure base URL is set, all XML loads must come from the same domain (unless the user has explicitly enabled cross-domain data access). For example, the following will return an E_ACCESSDENIED error.

pParser->SetSecureBaseURL(L"http://microsoft/");
pParser->SetURL(NULL, L"http://www.microsoft.com",FALSE);


Encoding Support

[Deprecated. Do not use. Superseded by SAX2 API/MSXML 3.0]

The same encoding support is provided for each of the different methods of input. To provide Unicode data, the input stream or buffer must start with a Unicode Byte Order Mark (BOM) 0xFFFE or 0xFEFF, depending on whether the Unicode is little or big endian. If no byte order mark is present, it is assumed to be UTF-8. To specify something other than UTF-8, use an XML declaration with an encoding attribute at the beginning of the input. For example, the following specifies a common encoding for Japanese on Microsoft® platforms.

<?xml version="1.0" encoding="shift_jis"?>

The XML parser recognizes UTF-8 and UCS-2 directly. For all other character sets, MLang is used to perform conversions.

Example Parser Usage

The following example assumes you have an IStream and NodeFactory already.

HRESULT ParseXML{IStream* input, IXMLNodeFactory* f)
{
    IXMLParser* xp;
    HRESULT hr;
    checkhr(CoCreateInstance(CLSID_XMLParser, NULL, CLSCTX_INPROC_SERVER,
      IID_IXMLParser, (void**)&xp);
    checkhr(xp->SetInput(input));
    checkhr(xp->SetFactory(f));
    hr = xp->Run(-1);
    xp->Release();
    return hr;
}


(Deprecated) IXMLNodeSource Interface

[Deprecated. Do not use. Superseded by SAX2 API/MSXML 3.0]

The IXMLNodeSource interface is defined as a base class for the IXMLParser so that other components can drive a NodeFactory without having to implement the full IXMLParser interface. For example, you might want to drive a NodeFactory from a component that extracts the data out of a database.

If a NodeFactory requires methods not defined here but on IXMLParser, it must do a QueryInterface for IXMLParser to see if it is really being driven by a parser or not, and if not, fail gracefully.

interface IXMLNodeSource : IUnknown
{
    HRESULT SetFactory(
        [in] IXMLNodeFactory* pNodeFactory);

    HRESULT GetFactory(
        [out] IXMLNodeFactory** ppNodeFactory);

    HRESULT Abort(
        [in] BSTR bstrErrorInfo);

    ULONG GetLineNumber();

    ULONG GetLinePosition();

    ULONG GetAbsolutePosition();

    HRESULT GetLineBuffer(
        [out] const WCHAR** ppwcBuf,
        [out] ULONG* pulLen,
        [out] ULONG* pulStartPos);

    HRESULT GetLastError();

    HRESULT GetErrorInfo(
        [out] BSTR* pbstrErrorInfo);

    ULONG GetFlags();

    HRESULT GetURL(
        [out] const WCHAR** ppwcBuf);
};

SetFactory, GetFactory

Use SetFactory to plug in your customer NodeFactory. The NodeSource (or parser) delegates to your NodeFactory for each element it finds in the XML source. Use GetFactory to get back your NodeFactory later. For more information, see NodeFactory Interface.

Abort

The NodeSource can be stopped by the caller or the NodeFactory at any time by calling Abort. If the NodeFactory calls Abort, it can also provide a BSTR that contains more information about why the node factory is aborting. This will then be returned from GetErrorInfo.

GetLineNumber, GetLinePosition, GetAbsolutePosition, GetLastError, GetErrorInfo

The current line position information can be queried at any time. The IXMLNodeFactory is given a pointer to the IXMLParser so that it can also use these functions. GetAbsolutePosition returns the absolute offset from the beginning of the input stream or buffer after UTF-8 decoding has been applied. Other types of NodeSources may not be able to provide this information. GetLastError returns the last HRESULT that was returned from other methods. GetErrorInfo returns a BSTR that contains more descriptive information about the error (the same BSTR that was provided to the Abort method).

GetLineBuffer

GetLineBuffer returns the current line of XML that is being parsed. When there is an error, it is helpful to see the original decoded XML that contained the error. ppwcBuf is a pointer into the decoded XML buffer. pulLen is the length of the buffer. pulStartPos is the position of the error inside the buffer. Other types of NodeSources may not be able to provide this information. GetLineBuffer is not guaranteed to always return something. If no parse has been started or if there was an error fetching any XML data, it returns an empty buffer of length 0.

GetFlags

The following flags can combined using OR to control how the parser works. By default none of these flags is set.

typedef enum
{
    XMLFLAG_FLOATINGAMP       = 1,
    XMLFLAG_SHORTENDTAGS      = 2,
    XMLFLAG_CASEINSENSITIVE   = 4,
    XMLFLAG_NONAMESPACES      = 8,
    XMLFLAG_NOWHITESPACE      = 16,
    XMLFLAG_IE4QUIRKS         = 32,
    XMLFLAG_NODTDNODES        = 64,
    XMLFLAG_IE4COMPATIBILITY  = 255,
} XML_PARSER_FLAGS;
XMLFLAG_FLOATINGAMP
This is a Microsoft® Internet Explorer 4.0 compatibility flag that allows your PCDATA to contain unescaped ampersand characters.
XMLFLAG_SHORTENDTAGS
This is an Internet Explorer 4.0 compatibility flag that allows short end tags </>.
XMLFLAG_CASEINSENSITIVE
This makes the parser case-insensitive; the text you get is whatever was in the original file. It does not fold to uppercase; this is inefficient and not always necessary.
XMLFLAG_NONAMESPACES
This indicates whether the namespace declarations and tag name syntax are recognized.
XMLFLAG_NOWHITESPACE
This indicates whether to return WHITESPACE nodes.
XMLFLAG_IE4QUIRKS
This is a miscellaneous flag for other Internet Explorer 4.0 compatibility issues, described as follows.

<x=> | This syntax error was allowed under Internet Explorer 4.0.
<!-- x -- y --> | Invalid "--" characters inside comments.
xml-space | Instead of xml:space.
<x y="1"z="2/> | White space between attributes not needed.
<x a="1" a="2"/> | Duplicate attributes.
<!-- top of doc --> | Comments before the <?xml declaration.
<x y="<z>"/> | The '<' character inside an attribute.
<x>]]></x> | ']]>' sequence inside PCDATA.

XMLFLAG_NODTDNODES
This turns off parsing of any internal document type definition (DTD) subset so that NodeFactories that do not care about DTDs do not need to deal with them at all.
XMLFLAG_IE4COMPATIBILITY
This is an OR of all of the above, which results in pretty good overall Internet Explorer 4.0 compatibility.

GetURL

For IXMLParser NodeSources, GetURL returns the URL provided in the IXMLParser SetURL() or Load() methods. Other NodeSources can return anything here.


(Deprecated) IXMLNodeFactory Interface

[Deprecated. Do not use. Superseded by SAX2 API/MSXML 3.0]

You implement the NodeFactory interface and plug it into the NodeSource (or IXMLParser). In the case of the IXMLParser, calls to the NodeFactory are made as it parses the XML document.

interface IXMLNodeFactory : IUnknown
{
    HRESULT NotifyEvent(
            [in] IXMLNodeSource* pSource,
            [in] XML_NODEFACTORY_EVENT iEvt);

    HRESULT BeginChildren(
            [in] IXMLNodeSource* pSource,
            [in] XML_NODE_INFO* pNodeInfo);

    HRESULT EndChildren(
            [in] IXMLNodeSource* pSource,
            [in] BOOL fEmpty,
            [in] XML_NODE_INFO* pNodeInfo);

    HRESULT Error(
            [in] IXMLNodeSource* pSource,
            [in] HRESULT hrErrorCode,
            [in] USHORT cNumRecs,
            [in] XML_NODE_INFO __RPC_FAR **aNodeInfo);

    HRESULT CreateNode(
            [in] IXMLNodeSource __RPC_FAR *pSource,
            [in] PVOID pNodeParent,
            [in] USHORT cNumRecs,
            [in] XML_NODE_INFO __RPC_FAR **aNodeInfo);
};

Node Info

The following XML_NODE_INFO structure helps you understand the preceding interface.

typedef struct _XML_NODE_INFO
{
    DWORD           dwSize;
    DWORD           dwType;
    DWORD           dwSubType;
    BOOL            fTerminal;
    WCHAR*          pwcText;
    ULONG           ulLen;
    ULONG           ulNsPrefixLen;
    PVOID           pNode;
    PVOID           pReserved;
} XML_NODE_INFO;
DWORD dwSize
The size of this structure in bytes.
DWORD dwType
The node type.
DWORD dwSubType
The node subtype.
BOOL fTerminal
True if this node cannot have any children. BeginChildren and EndChildren are guaranteed not to be called for this node.
const WCHAR* pwcText
This is either a tag name or a PCDATA text value. The lifetime of this pointer is the lifetime of the CreateNode call. Element, attribute, and processing instruction tag names or attribute values of type ID, NMTOKEN, ENTITY, or NOTATION can have namespace prefixes.
ULONG ulLen
The length of the element or attribute name.
ULONG ulNsPrefixLen
The length of the namespace prefix, when present.
PVOID pNode
This field can be used by the NodeFactory to RETURN an object representing the node. Because this is PVOID, the NodeFactory can build any tree representation, even a raw struct hierarchy.
PVOID * pReserved
For private communication between factories.

This is essentially a callback interface so that custom node factories can build different kinds of object hierarchies that reflect the XML document. The NodeFactory does not have to create anything; it can just be searching for something in the XML document.

If a non-NULL pointer is returned in the pNode field of the NodeInfo struct, this will be passed back in by the parser as the pNodeParent in subsequent calls to CreateNode for the children of that node. In other words, the XML parser maintains the parse context for you and passes in the appropriate parent pointer based on what it finds in the XML. The pNodeParent for root level nodes is equal to the argument provided in the SetRoot call on the parser.

If your Node objects must be reference counted, AddRef before returning them, and then Release them in EndChildren. You must also release all nodes provided in the Error method in case the parser stops on an XML syntax error. The parser guarantees to call Error in all cases, so you do not have to worry about leaking nodes.

NotifyEvent

This is a convenience method that tells the NodeFactory where it is in the XML document. Possible events are described here.

XMLNF_STARTDOCUMENT
This event is fired at the start of the document.
XMLNF_STARTDTD
The parser is about to start parsing a document type definition (DTD) file.
XMLNF_ENDDTD
The DTD is finished.
XMLNF_STARTDTDSUBSET
The parser is about to start the DTD internal subset.
XMLNF_ENDDTDSUBSET
The internal subset is finished.
XMLNF_ENDPROLOG
This event is fired just prior to the CreateNode call for the root element for the document. In other words, all the initial XML declarations, processing instructions, and comments are done.
XMLNF_STARTENTITY
This event is called prior to ENDENTITY. This happens when you call ParseEntity on the IXMLParser.
XMLNF_ENDENTITY
This event is used in conjunction with ParseEntity. This indicates the entity is finished.
XMLNF_ENDDOCUMENT
This event is used at the end of the document.
XMLNF_DATAAVAILABLE
This is a regular event to tell the node factory more data has just arrived.

BeginChildren

The BeginChildren method is called when a node can contain children. For example, the following node can contain children.

<foo name="123">

Nodes that are empty, such as comment, CDATA, and text nodes, will not have a BeginChildren call.

<foo name="123"/>

You can tell if a node was empty at EndChildren time by checking the Boolean argument fEmpty.

EndChildren

The EndChildren method is called when all the subelements of the given element are complete (in other words, the matching end tag </FOO> has been reached). This is also called if the tag is an empty tag <FOO ... />, in which case the fEmpty argument is set to TRUE in case the NodeFactory must distinguish between this case and <FOO></FOO>. This method is not called for terminal nodes.

Error

The Error method is called when the parser runs into an error in the XML document. The parser will stop and return the HRESULT error code to the caller. The NodeFactory can call back to the parser to get more information about the error.

CreateNode

CreateNode is the main method that gets called during parsing for every element.

IXMLNodeSource* pNodeSource
The node source is passed into each node factory call so that the node factory can call back and get important information, such as the current line number, or stop the parser.
PVOID* pNodeParent
This is the parent object of the node being created. This parent pointer was returned from a prior CreateNode call or is the root object provided using the parser SetRoot method.
USHORT cNumRecs
Number of XML_NODE_INFO structs.
XML_NODE_INFO **aNodeInfo
Pointer to an array of pointers to XML_NODE_INFO structures. The first member is the node information for the elements. The second through last members of the array contain attribute name nodes, followed by attribute value nodes. For example, if we have <a y="2" x="foo&bar;blech">, the array looks like the following.

Element "a"
Attribute "y"
#PCDATA "2"
Attribute "x"
#PCDATA "foo"
EntityRef "bar"
#PCDATA "more...."

HRESULT
Consider the following XML fragment.
<item id="FOO" ms:price="20" title="BAR &foo;" xmlns:price="URIXXX" >
  <value>The quick brown fox</value>
  <dsig id="1412231"/>
</item>

The following sequence of calls will be made on the node factory. This example is indented for readability only. It is not meant to imply recursion.

CreateNode XML_ELEMENT: [item]
           XML_ATTRIBUTE: [id]
           XML_PCDATA: [FOO]
           XML_ATTRIBUTE: [ms][price]
           XML_PCDATA: [20]
           XML_ATTRIBUTE: [title]
           XML_PCDATA: [BAR ]
           XML_ENTITYREF: [foo]
           XML_ATTRIBUTE: [xmlns][price]
           XML_PCDATA: [URIXXX]
BeginChildren
  CreateNode XML_WHITESPACE: 0D0A09 (fTerminal=TRUE)
  CreateNode XML_ELEMENT: [value]
  BeginChildren
    CreateNode XML_PCDATA: [The quick brown fox](fTerminal=TRUE)
  EndChildren
  CreateNode XML_WHITESPACE: 0D0A09 (fTerminal=TRUE)
  CreateNode XML_ELEMENT: [dsig]
             XML_ATTRIBUTE: [id]
             XML_PCDATA: [1412231]
  EndChildren (fEmpty=TRUE)
  CreateNode XML_WHITESPACE: 0D0A (fTerminal=TRUE)
EndChildren
  • When fTerminal is True, there are no BeginChildren or EndChildren. This happens when the node type implies that there can never be any child nodes according to the XML language specification.
  • Empty tags (like the dsig tag) do not have a BeginChildren; however, they do have an EndChildren that specifies the fEmpty argument as TRUE.
  • XML_ATTRIBUTE nodes can have multiple child nodes as shown in the case where the title attribute contains both XML_PCDATA and an XML_ENTITYREF node.
  • XML_WHITESPACE nodes can usually be entirely ignored by your node factory (which is why they are different from XML_PCDATA) unless your node factory cares about preserving the original document format.


Node Types Reference

[Deprecated. Do not use. Superseded by SAX2 API/MSXML 3.0]

This is the complete set of node types and when they occur. There are two main types of nodes, those that can have children (containers) and those that cannot (terminal nodes). The second column in the following tables show the possible subtypes that can appear for that given node type. If the subtype is not one of those listed, it will be zero.


Containers

[Deprecated. Do not use. Superseded by SAX2 API/MSXML 3.0]
XML_ELEMENT
At the start of a new element <foo.….
XML_ATTRIBUTE
At the start of a new attribute FOO="…." Possible subtypes are as follows.

XML_VERSION | Version attribute of XML declaration.
XML_ENCODING | Encoding attribute of XML declaration.
XML_STANDALONE | Standalone attribute of XML declaration.
XML_NS | The special xmlns:foo attribute. (Note: might be just xmlns=).
XML_NS | The special xmlns:foo attribute. (Note: might be just xmlns=).
XML_XMLSPACE | The special xml:space attribute.
XML_XMLLANG | The special xml:lang attribute.

XML_DTDATTRIBUTE
For attributes inside document type definition (DTD) elements, including <!DOCTYPE:

XML_SYSTEM | SYSTEM literal
XML_PUBLIC | PUBLIC literal
XML_NDATA | The NDATA attribute on an <!ENTITY declaration.

XML_PI
The start of a <?foo with text equal to processing instruction name.
XML_XMLDECL
This the special <?xml ... processing instruction. In this case, the parser parses the version, encoding, and standalone attributes, and passes these as special node types. For more information, see XML_VERSION, XML_ENCODING, and XML_STANDALONE.
XML_DOCTYPE
This is the special <!DOCTYPE declaration. The text is the doctype name. This will be followed by an optional XML_PUBLIC or XML_SYSTEM node and an optional XML_DTDSUBSET. If there is a 'PUBLIC' keyword, you will get XML_PUBLIC with the text of the public id, followed by XML_SYSTEM with the text of the system literal.
XML_ENTITYDECL
<!ENTITY ... This will be followed by STRING and NAME nodes. If the subtype is XML_ELEMENTDECL, this is a parameter entity declaration.
XML_ELEMENTDECL
<!ELEMENT ... This will be followed by content model nodes, XML_GROUP, XML_NAME, XML_CHOICE, XML_SEQUENCE, XML_STAR, XML_PLUS, XML_QUESTIONMARK, and so on.
XML_ATTLISTDECL
<!ATTLIST ... This will be followed by STRING and NAME nodes.
XML_NOTATION
<!NOTATION ... This will be followed by STRING and NAME nodes.
XML_GROUP
The ( ... ) grouping in content models.
XML_INCLUDESECT
<!INCLUDE[.., conditional section in a DTD. The children of this will be the DTD declarations in this include section.


Terminal Nodes

[Deprecated. Do not use. Superseded by SAX2 API/MSXML 3.0]
XML_PCDATA
The text inside a node or an attribute.
XML_CDATA
The text inside <![CDATA[...]]>.
XML_IGNORESECT
<!IGNORE[.., conditional section in a document type definition (DTD). The text value of this node type is the entire contents of the section of the DTD that is being ignored.
XML_COMMENT
The text inside '<!--' and '-->'.
XML_ENTITYREF
A named entity node, &foo;.
XML_WHITESPACE
White space between elements.
XML_NAME
General name for certain attribute values based on DTD declarations.
XML_NMTOKEN
General name token for certain typed attribute values or DTD declarations.
XML_STRING
General quoted string literal in DTD declarations.
XML_PEREF
%foo;
XML_MODEL
The pieces of a content model in an element declaration. Possible subtypes are as follows.

XML_EMPTY | keyword EMPTY
XML_ANY | keyword ANY
XML_MIXED | keyword #PCDATA
XML_EMPTY | keyword EMPTY
XML_SEQUENCE ,
XML_CHOICE |
XML_STAR +
XML_PLUS *
XML_QUESTIONMARK ?

XML_ATTDEF
Name of attribute being defined in an ATTLIST declaration.
XML_ATTTYPE
The type of an attribute being defined. Possible subtypes are as follows.

XML_AT_CDATA | Attribute is just raw text. No particular type.
XML_AT_ID | Attribute is supposed to contain an ID that is unique to the document.
XML_AT_IDREF | Attribute will reference another attribute of type ID.
XML_AT_IDREFS | Attribute will contain multiple ID references separated by spaces.
XML_AT_ENTITY | Attribute is the name of an unparsed entity. An unparsed entity is an entity declared with the NDATA keyword.
XML_AT_ENTITIES | Attribute points to multiple unparsed entities.
XML_AT_NMTOKEN | Attribute value must comply with rules for parsing name tokens.
XML_AT_NMTOKENS | Attribute value contains multiple name tokens.
XML_AT_NOTATION | Attribute value points to one or more declared notations.

XML_ATTPRESENCE
Defines the presence rules for the attribute. Possible subtypes are as follows.

XML_AT_REQUIRED | Attribute is required to be present in the data.
XML_AT_IMPLIED | Attribute is optional.
XML_AT_FIXED | Attribute has a fixed value and is therefore typically not present in the instance data.

XML_DTDSUBSET
This marks the beginning of an internal subset containing DTD information.


Error Codes

[Deprecated. Do not use. Superseded by SAX2 API/MSXML 3.0]

Possible error codes include S_OK, E_PENDING, E_FAIL, E_OUTOFMEMORY, and the following parser specific errors.

XML_E_FORMATINDEX_BADINDEX | 0xC00CE306 | The value passed in to formatIndex must be greater than 0.
XML_E_FORMATINDEX_BADFORMAT | 0xC00CE307 | Invalid format string.
XML_E_EXPECTED_TOKEN | 0xC00CE380 | Expected token %1 found %2.
XML_E_UNEXPECTED_TOKEN | 0xC00CE381 | Unexpected token %1.
XML_E_MISSINGEQUALS | 0xC00CE501 | Missing equals sign between attribute and attribute value.
XML_E_MISSINGQUOTE | 0xC00CE502 | A string literal was expected, but no opening quote character was found.
XML_E_COMMENTSYNTAX | 0xC00CE503 | Incorrect syntax was used in a comment.
XML_E_BADSTARTNAMECHAR | 0xC00CE504 | A name was started with an invalid character.
XML_E_BADNAMECHAR | 0xC00CE505 | A name contained an invalid character.
XML_E_BADCHARINSTRING | 0xC00CE506 | A string literal contained an invalid character.
XML_E_XMLDECLSYNTAX | 0xC00CE507 | Invalid syntax for an XML declaration.
XML_E_BADCHARDATA | 0xC00CE508 | An invalid character was found in text content.
XML_E_MISSINGWHITESPACE | 0xC00CE509 | Required white space was missing.
XML_E_EXPECTINGTAGEND | 0xC00CE50A | The character '>' was expected.
XML_E_BADCHARINDTD | 0xC00CE50B | Invalid character found in document type definition (DTD).
XML_E_BADCHARINDECL | 0xC00CE50C | An invalid character was found inside a DTD declaration.
XML_E_MISSINGSEMICOLON | 0xC00CE50D | A semicolon character was expected.
XML_E_BADCHARINENTREF | 0xC00CE50E | An invalid character was found inside an entity reference.
XML_E_UNBALANCEDPAREN | 0xC00CE50F | Unbalanced parentheses.
XML_E_EXPECTINGOPENBRACKET | 0xC00CE510 | An opening '[' character was expected.
XML_E_BADENDCONDSECT | 0xC00CE511 | Invalid syntax in a conditional section.
XML_E_INTERNALERROR | 0xC00CE512 | Internal error.
XML_E_UNEXPECTED_WHITESPACE | 0xC00CE513 | White space is not allowed at this location.
XML_E_INCOMPLETE_ENCODING | 0xC00CE514 | End of file reached in invalid state for current encoding.
XML_E_BADCHARINMIXEDMODEL | 0xC00CE515 | Mixed content model cannot contain this character.
XML_E_MISSING_STAR | 0xC00CE516 | Mixed content model must be defined as zero or more('*').
XML_E_BADCHARINMODEL | 0xC00CE517 | Invalid character in content model.
XML_E_MISSING_PAREN | 0xC00CE518 | Missing parenthesis.
XML_E_BADCHARINENUMERATION | 0xC00CE519 | Invalid character found in ATTLIST enumeration.
XML_E_PIDECLSYNTAX | 0xC00CE51A | Invalid syntax in processing instruction declaration.
XML_E_EXPECTINGCLOSEQUOTE | 0xC00CE51B | A single or double closing quote character (\' or \") is missing.
XML_E_MULTIPLE_COLONS | 0xC00CE51C | Multiple colons are not allowed in a name.
XML_E_INVALID_DECIMAL | 0xC00CE51D | Invalid character for decimal digit.
XML_E_INVALID_HEXIDECIMAL | 0xC00CE51E | Invalid character for hexadecimal digit.
XML_E_INVALID_UNICODE | 0xC00CE51F | Invalid Unicode character value for this platform.
XML_E_WHITESPACEORQUESTIONMARK | 0xC00CE520 | Expecting white space or '?'.
XML_E_SUSPENDED | 0xC00CE550 | The parser is suspended.
XML_E_STOPPED | 0xC00CE551 | The parser is stopped.
XML_E_UNEXPECTEDENDTAG | 0xC00CE552 | End tag was not expected at this location.
XML_E_UNCLOSEDTAG | 0xC00CE553 | The following tags were not closed: %1.
XML_E_DUPLICATEATTRIBUTE | 0xC00CE554 | Duplicate attribute.
XML_E_MULTIPLEROOTS | 0xC00CE555 | Only one top level element is allowed in an XML document.
XML_E_INVALIDATROOTLEVEL | 0xC00CE556 | Invalid at the top level of the document.
XML_E_BADXMLDECL | 0xC00CE557 | Invalid XML declaration.
XML_E_MISSINGROOT | 0xC00CE558 | XML document must have a top level element.
XML_E_UNEXPECTEDEOF | 0xC00CE559 | Unexpected end of file.
XML_E_BADPEREFINSUBSET | 0xC00CE55A | Parameter entities cannot be used inside markup declarations in an internal subset.
XML_E_PE_NESTING | 0xC00CE55B | The replacement text for a parameter entity must be properly nested with parenthesized groups.
XML_E_INVALID_CDATACLOSINGTAG | 0xC00CE55C | The literal string ']]>' is not allowed in element content.
XML_E_UNCLOSEDPI | 0xC00CE55D | Processing instruction was not closed.
XML_E_UNCLOSEDSTARTTAG | 0xC00CE55E | Element was not closed.
XML_E_UNCLOSEDENDTAG | 0xC00CE55F | End element was missing the character '>'.
XML_E_UNCLOSEDSTRING | 0xC00CE560 | A string literal was not closed.
XML_E_UNCLOSEDCOMMENT | 0xC00CE561 | A comment was not closed.
XML_E_UNCLOSEDDECL | 0xC00CE562 | A declaration was not closed.
XML_E_UNCLOSEDMARKUPDECL | 0xC00CE563 | A markup declaration was not closed.
XML_E_UNCLOSEDCDATA | 0xC00CE564 | A CDATA section was not closed.
XML_E_BADDECLNAME | 0xC00CE565 | Declaration has an invalid name.
XML_E_BADEXTERNALID | 0xC00CE566 | External ID is invalid.
XML_E_BADELEMENTINDTD | 0xC00CE567 | An XML element is not allowed inside a DTD.
XML_E_RESERVEDNAMESPACE | 0xC00CE568 | The namespace prefix is not allowed to start with the reserved string "xml".
XML_E_EXPECTING_VERSION | 0xC00CE569 | The 'version' attribute is required at this location.
XML_E_EXPECTING_ENCODING | 0xC00CE56A | The 'encoding' attribute is required at this location.
XML_E_EXPECTING_NAME | 0xC00CE56B | At least one name is required at this location.
XML_E_UNEXPECTED_ATTRIBUTE | 0xC00CE56C | The specified attribute was not expected at this location. The attribute may be case sensitive.
XML_E_ENDTAGMISMATCH | 0xC00CE56D | End tag '%2' does not match the start tag '%1'.
XML_E_INVALIDENCODING | 0xC00CE56E | System does not support the specified encoding.
XML_E_INVALIDSWITCH | 0xC00CE56F | Switch from current encoding to specified encoding not supported.
XML_E_EXPECTING_NDATA | 0xC00CE570 | NDATA keyword is missing.
XML_E_INVALID_MODEL | 0xC00CE571 | Content model is invalid.
XML_E_INVALID_TYPE | 0xC00CE572 | Invalid type defined in ATTLIST.
XML_E_INVALIDXMLSPACE | 0xC00CE573 | XML space attribute has invalid value. Must specify 'default' or 'preserve'.
XML_E_MULTI_ATTR_VALUE | 0xC00CE574 | Multiple names found in attribute value when only one was expected.
XML_E_INVALID_PRESENCE | 0xC00CE575 | Invalid ATTDEF declaration. Expected #REQUIRED, #IMPLIED or #FIXED.
XML_E_BADXMLCASE | 0xC00CE576 | The name 'xml' is reserved and must be lowercase.
XML_E_CONDSECTINSUBSET | 0xC00CE577 | Conditional sections are not allowed in an internal subset.
XML_E_CDATAINVALID | 0xC00CE578 | CDATA is not allowed in a DTD.
XML_E_INVALID_STANDALONE | 0xC00CE579 | The standalone attribute must have the value 'yes' or 'no'.
XML_E_UNEXPECTED_STANDALONE | 0xC00CE57A | The standalone attribute cannot be used in external entities.
XML_E_DOCTYPE_IN_DTD | 0xC00CE57B | Cannot have a DOCTYPE declaration in a DTD.
XML_E_MISSING_ENTITY | 0xC00CE57C | Reference to undefined entity.
XML_E_ENTITYREF_INNAME | 0xC00CE57D | Entity reference is resolved to an invalid name character.
XML_E_DOCTYPE_OUTSIDE_PROLOG | 0xC00CE57E | Cannot have a DOCTYPE declaration outside of a prolog.
XML_E_INVALID_VERSION | 0xC00CE57F | Invalid version number.
XML_E_DTDELEMENT_OUTSIDE_DTD | 0xC00CE580 | Cannot have a DTD declaration outside of a DTD.
XML_E_DUPLICATEDOCTYPE | 0xC00CE581 | Cannot have multiple DOCTYPE declarations.
XML_E_RESOURCE | 0xC00CE582 | Error processing resource '%1'.


XML Schemas

[This is preliminary documentation and subject to change.]

Similar to data modeling in a relational database, a schema provides a way to define the structure of XML documents. A schema specifies the elements that can be used in XML documents along with the structure that these elements must follow in order to be valid for that specific schema.

In other words, a schema describes the vocabulary (rules or grammar) that complying XML documents must follow in order to be considered schema-valid with that particular schema. Validation of XML documents ensures that the external data conforms to the rules (grammar) required by the schema.

To learn about | See
Benefits of XML Schemas, frequently asked questions (FAQs) | Getting Started with XML Schemas
Using Namespaces in Schemas | Using Namespaces in Schemas
Data Types in Schemas | Data Types in Schemas
Structures | Schema Structures
Validation | Validation
Reference information on XML schemas (XSD) | XML Schema Reference (XSD)
Developing XDR schemas (XML-Data Reduced language) | XDR Developer's Guide
Reference information on XDR schemas (XML-Data Reduced language) | XDR Schema Reference


Getting Started with XML Schemas

[This is preliminary documentation and subject to change.]

XML schemas are powerful and complex tools for creating structure and validating that structure in compliant XML documents. Schemas are XML files that have an .xsd file extension. Schemas describe the contents of an XML documents using valid XML; elements and attributes are declared using element and attribute elements.

An organization and its partners can benefit by using schemas to exchange data (through schema-compliant XML documents). Schemas are also useful for keeping XML documents consistent throughout an organization.

This section provides information to help you get started with XML schemas.

Frequently Asked Questions about Schemas

Comparing Schema Languages

Version and Conformance


Frequently Asked Questions about Schemas

[This is preliminary documentation and subject to change.]

The following list includes frequently asked questions about schemas.

What is the difference between a declaration and a definition?

What is the difference between XSD schema and XDR schema?

What is the difference between a declaration and a definition?

Declarations describe the content models (structure) of elements and attributes inside XML document instances. Definitions create new data types (simple and complex types).

Return to top

What is the difference between XSD schema and XDR schema?

The XML Schema Definition (XSD) language is the current World Wide Web Consortium(W3C) specification for XML schemas. The XML-Data Reduced Language (XDR) is an interim schema language offered to developers while the W3C worked on a draft implementation. MSXML 4.0 supports both XSD and XDR.

Return to top


Comparing Schema Languages

[This is preliminary documentation and subject to change.]

This section compares schema languages to help you make decisions about implementing schemas into your XML applications.

Document Type Definitions (DTDs)

DTDs specify content models for a set of XML documents.

  • DTDs keep XML documents consistent.
  • DTDs can be shared.
  • DTDs provide a formal and complete definition of an XML vocabulary.
  • DTDs are restricted to one DTD for each XML document.

Schemas

Like a DTD, a schema can specify the structure or model of a particular set of documents. The following are the benefits of using a schema language to describe the document structure.

  • Schemas use XML syntax.
  • Schemas can be parsed by an XML parser.
  • Schemas provide support for data types; the type of data contained in an element can be specified.
  • Schemas allow global elements (elements that must be used the same way throughout the XML document) and local elements (elements that have a specific meaning in context).
  • Schemas offer data type support (integer, string, Boolean), and the ability to create other data types.

Support for XDR schemas

The following products support the XML-Data Reduced Language (XDR) schemas:

  • Microsoft® Biztalk™ Server
  • Microsoft SQL Server™ 2000
  • Microsoft Office 2000
  • Microsoft Internet Explorer 5.0 and later

XDR schemas also have tools support in the following products:

  • Extensibility's XML Authority

XSD Schemas

The World Wide Web Consortium (W3C) is nearing completion on the Candidate Recommendation of the XML Schemas specification. XML Schema Definition (XSD) schemas provide support for data types and defining structures. This support allows you to create robust XSD schemas and validate XML instance documents against these schemas.

See Also

XDR Schema Developer's Guide


Version and Conformance

[This is preliminary documentation and subject to change.]

The latest version of the Microsoft XML Parser (MSXML 4.0) complies with the Worldwide Web Consortium (W3C) XML Schema Candidate Recommendation (March 2001).

Version | Support
MSXML | No support for schemas.
MSXML 2.0 | Support for XML-Data Reduced (XDR) schemas.
MSXML 2.6 | Support for XDR schemas.
MSXML 3.0 | Support for XDR schemas.
MSXML 4.0 | Support for XML Schema Definition (XSD) and XDR schemas.

W3C status

The W3C XML Schema specification is in the candidate recommendation status. The W3C XML Schema Working Group considers the schema specifications to be stable and is encouraging developers to implement the specification. Microsoft is committed to complying with the W3C standards and has updated MSXML to meet the released specifications.


Validation

[This is preliminary documentation and subject to change.]

Validation is the process of comparing an XML document to a corresponding schema. If an XML document conforms to all of the rules in the schema, the document is considered valid. As an introduction to validation, this section provides the following topics:

Validation Overview

Validating an XML Document Against an XSD Schema

Note For the MSXML 4.0 Technology Preview, validation is supported with the DOM through the use of IXMLDOMSchemaCollection/XMLSchemaCache. The schema schemaLocation and xsi:schemaLocation attributes are not supported in this technology preview. SAX currently does not support validation.

See Also

IXMLDOMSchemaCollection/XMLSchemaCache

Other Resources Other Resources

World Wide Web Consortium (W3C) XML Schema Part 2: Datatypes | World Wide Web Consortium (W3C) XML Schema Part 1: Structures


Validation Overview

A schema defines the structure of XML documents. It provides details about the content model: which elements it contains and in what order, what its content can be, and which content these attributes can contain.

A schema verifies that the incoming XML documents are in the expected format.

An XML schema can be used to:

  • Validate the content of an XML document.
  • Determine whether the XML document is a valid instance of the vocabulary (grammar or rules) expressed by the XML schema.
  • Describe the vocabulary for use by others creating XML documents.
  • Define the elements that can appear within an XML document and the attributes that can be associated with an element.
  • Define whether an element is empty or can include text.
  • Define a default value for an attribute.
  • Define elements that can contain child elements.
  • Define the sequence for child elements that appear in an element.
  • Define the number of child elements.

Writing validation rules

The following can be used to write validation rules.

  • Document Type Definition (DTD)
  • XML-Data Reduced Language (XDR)
  • XML Schema Definition (XSD)


Validating an XML Document Against an XSD Schema

With the MSXML 4.0 Technology Preview, you can validate an XML document against an XSD schema. To validate a document, add the schema to the XMLSchemaCache object, set the schemas property of a DOMDocument object to reference the schema in the XMLSchemaCache object, and then load the XML file you want to validate into the DOMDocument object. Validation is performed when the document is loaded into the DOMDocument object. Validation errors are handled using the parseError property of the DOMDocument object. This topic provides a quick example of how to validate a document against a schema and consists of the following.

books.xsd
The XSD schema that is used to validate the books.xml file.
books.xml
The file that is loaded and validated against the books.xsd schema.
Microsoft Visual Basic validation code
Creates an XMLSchemaCache object, adds the schema to it, and sets the schemas property of the DOMDocument object to reference the schema in the XMLSchemaCache object. In addition, the code loads the document into the DOMDocument object and returns any validation errors that occur.

To get started

  1. Open Visual Basic 6.0, and in the New Project dialog box, double-click Standard EXE.
  2. On the Project menu, click References.
  3. In the Available References list, select Microsoft XML,v4.0, and then click OK.
  4. Add a Command button to Form1.
  5. Save the project to a folder on your hard drive.

The XML Document (books.xml)

The books.xml file used in this example, shown below, is a modified version of the books.xml file used throughout the MSXML SDK. Notice that "urn:books" is declared as the default namespace for this document.

If you want to run the example in this topic, copy the following code to a text editor, such as Notepad, and then save the file as books.xml.

<?xml version="1.0"?>
<x:catalog xmlns:x="urn:books">
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications with
      XML.</description>
      <title>2000-10-01</title>
   </book>
</x:catalog>

The XSD Schema (books.xsd)

The following document shows the books.xsd schema used in this example.

If you want to run the example in this topic, copy the following code to a text editor, such as Notepad, and then save the file as books.xsd.

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="catalog" type="CatalogData"/>

  <xsd:complexType name="CatalogData">
    <xsd:sequence>
      <xsd:element name="book" type="bookdata" minOccurs="0"
      maxOccurs="unbounded"/>
      </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="bookdata">
    <xsd:sequence>
      <xsd:element name="author" type="xsd:string"/>
      <xsd:element name="title" type="xsd:string"/>
      <xsd:element name="genre" type="xsd:string"/>
      <xsd:element name="price" type="xsd:float"/>
      <xsd:element name="publish_date" type="xsd:date"/>
      <xsd:element name="description" type="xsd:string"/>
    </xsd:sequence>
    <xsd:attribute name="id" type="xsd:string"/>
  </xsd:complexType>
</xsd:schema>

Visual Basic Validation Code

The following code snippet shows how you can perform validation on the books.xml document. This code creates an XMLSchemaCache40 object, adds the namespace URI declaration ("urn:books") and the schema (books.xsd) to the object, and then references the schema using the schemas property of the DOMDocument object. Validation is performed when the books.xml file is loaded into the DOMDocument object. Validation errors are returned using the parseError property of the DOMDocument object.

To run the example

  1. Copy the code shown below to the Command1_Click procedure.
    Private Sub Command1_Click()
Dim xmlschema As MSXML2.XMLSchemaCache
Set xmlschema = New MSXML2.XMLSchemaCache
xmlschema.Add "urn:books", App.Path & "\books.xsd"
Dim xmldom As MSXML2.DOMDocument
Set xmldom = New MSXML2.DOMDocument
Set xmldom.schemas = xmlschema

xmldom.async = False
xmldom.Load App.Path & "\books.xml"

If xmldom.parseError.errorCode <> 0 Then
    MsgBox xmldom.parseError.errorCode & " " & xmldom.parseError.reason
Else
    MsgBox "No Error"
End If
End Sub
  2. On the Visual Basic toolbar, click Start, and then click the Command1 button on form1.

    When you run the example, it returns a "No Errors" message box.

Testing the Validation Code

To generate an error message for the validation code, change the books.xml document so the <title> element appears directly after the <catalog> element, as shown in bold in the following example. This makes the document invalid according to the books.xsd schema. Save the books.xml file and then run the Visual Basic code. The code returns the following error message:

"1072898028 Element content is invalid according to DTD/Schema. Expecting: book."

<?xml version="1.0"?>
<x:catalog xmlns:x="urn:books">
 <title>2000-10-01</title>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications with
      XML.</description>
   </book>

See Also

XML Schema Examples | XML Schema Element Map | XML Schema Elements | XML Data Types Reference | Primitive XML Data Types | Derived XML Data Types | Data Type Facets | IXMLDOMSchemaCollection/XMLSchemaCache

Other Resources Other Resources

World Wide Web Consortium (W3C) XML Schema Part 2: Datatypes | World Wide Web Consortium (W3C) XML Schema Part 1: Structures


Using Namespaces in Schemas

[This is preliminary documentation and subject to change.]

Schemas are a collection of rules (also referred as a grammar or vocabulary) that consist of type definitions (simple and complex), as well as element and attribute declarations. Because XML documents can have several vocabularies to describe different elements and attributes, the use of namespaces and prefixes removes ambiguity for element and attribute declarations. Distinguishing between element and attribute names is essential when you use schemas from more than one namespace.

A namespace is usually a string used to differentiate between the namespaces, such as "urn:www.microsoft.com", "http://www.microsoft.com", "http://www.w3c.org/2001/XMLSchema", and "uuid:1234567890".

XML Schema Preamble

An XML schema consists of a preamble that is followed by declarations. The preamble can contain three optional attributes within the schema element.

Example

The following syntax uses the schema element and references three commonly used XML vocabularies using the xmlns attribute.

<schema
xmlns="http://www.w3c.org/2001/XMLSchema" xmlns:xsd="http://www.w3c.org/2001/XMLSchema-datatypes" xmlns:xsi="http://www.w3c.org/2001/XMLSchema-instances"
version"1.0">
</schema>

The schema element uses its attributes to identify any external schemas that are to be used by the schema and all of its child elements.

The first two attributes use XML namespaces to identify the two World Wide Web Consortium (W3C) schema specifications that are used by most XML schemas. The first xmlns attribute includes the basic XML schema elements such as element, attribute, complexType, group, simpleType, and so forth. The second xmlns attribute defines the standard XML schema data types such as string, float, integer, and so forth.

Default namespaces

For a XML Schema Definition (XSD) schema, the schema has a top-level schema (XSD) element. The schema (XSD) element definition must include the following namespace.

http://www.w3.org/2001/XMLSchema

It is not necessary to use xsd or xsi as the namespace identifiers. You can use any prefix that does not conflict with the W3C namespaces that identify the XML schema specifications, however, xsd and xsi are the recommended conventions.

If you identify the W3C namespace as the default namespace, you do not need to include the prefix in every XML schema declaration and can use unqualified names such as <element>.

Specifying the version

The version attribute is informational and represents the version number of the schema. The XML application might want to ensure that a specific version of a schema is used to validate XML documents. You can use multiple versions: one for development and another for testing and another for production purposes and different ones for individual international markets or regional markets.

Example

The following syntax instructs the XML parser to use XSD schema, <xsd:schema>, to validate the structure and content of an element.

<xsd:schema
xmlns:xsd="http://www.w3c.org/2001/XMLSchema" xmlns:msc="http://tempuri.org/myschema">
  <element name="Price" type="msc:mydecimal"/>
</schema>

For XML Data Reduced (XDR) schemas, the Schema (XDR) element must include the following namespace.

urn:schemas-microsoft-com:xml-data

To use XML Data Reduced (XDR) data types, the Schema (XDR) element must include the following namespaces.

urn:schemas-microsoft-com:xml-data
urn:schemas-microsoft-com:datatypes

Example

The following syntax instructs the XML parser to use XDR schema, x-schema, to validate the structure and content of an element.

<BOOK xmlns="x-schema:http://www.microsoft.com/BookInfo.xml">
  <TITLE>A Suitable Boy</TITLE>
  <PRICE currency="US Dollar">22.95</PRICE>
</BOOK>

The x-schema identifier at the start of the namespace URI instructs the XML parser to treat the reference as a valid reference to an XDR schema; it retrieves the schema from the URL and validates against it.

For more information about declaring namespaces, namespace prefixes, and namespace scope, see Using Namespaces in Documents.


Data Types in Schemas

[This is preliminary documentation and subject to change.]

Schemas are powerful tools for creating structures because they support a rich set of data types.

The following topics describe the data types in schemas.

Primitive and Derived Data Types

Atomic, List, and Union Data Types

Anonymous and Named Data Types

Parts of Data Types


Primitive and Derived Data Types

[This is preliminary documentation and subject to change.]

There are two basic kinds of data types: primitive data types and derived data types.

Primitive Data Types

Primitive data types are those that are not defined in terms of other data types. Because primitive data types are the basis for all other types, they cannot have element content or attributes. However, they can contain values. Primitive data types are built into XML schemas. Examples of primitive data types are string, float, decimal, uriReference, and Qname.

For more information, see Primitive Data Types (XSD).

Derived Data Types

Derived data types are those that are defined in terms of other data types, called base types. Derived types may have attributes, and may have element or mixed content. Instances of derived types can contain any well-formed XML that is valid according to their data type definition. They may be built-in or user-derived. Base types can be primitive types or derived data types. Derived data types are created using extension and restriction facets. They can be built-in or user-derived data types.

New types may be derived from either a primitive type or another derived type. For example, integers are a subset of real numbers. Therefore, the XML schema integer type is derived from the decimal number type, which is its base type. We can, in turn, derive an even more restricted type of integer by using the minInclusive and maxInclusive elements. This is an example of a XML schema structure known as a simple type definition.

Example

The following example shows a simpleType element that defines a derived data type, integer, that is restricted to negative values.

<simpleType name="negativeInteger">
   <restriction base="xsi:integer">
      <minInclusive value="unbounded" />
      <maxInclusive value="-1" />
   </restriction>
</simpleType>

As with the primitive types, the W3C has defined a set of built-in derived data types. These types are part of the W3C XML schemas specification.

For a list of built-on derived types, see Derived Data Types (XSD).


Atomic, List, and Union Data Types

[This is preliminary documentation and subject to change.]

Atomic Data Types

Atomic data types have values that cannot be divided or broken down further. Atomic data types can be either primitive or derived.

Numbers and strings are atomic data types because their values cannot be described using smaller parts. XML schema has no concept of a character as a data type and a string is an atomic primitive type.

Example

The following is an example of an atomic data type of string.

<atomString>This cannot be divided further because this is a string.</atomString>

Example

The following is an example of an atomic derived type that is a date that can be derived from the string primitive type.

<atomDate>03-18-2001</atomDate>

List Data Types

List data types have values that consist of a finite length sequence of values of an atomic data type. List data types are comprised of sequences of atomic data types. Each part of a list data type carries a meaningful value.

There are three built-in list types: NMTOKENS, IDREFS, and ENTITIES.

Union Data Types

Union data types are those whose value spaces and lexical spaces are the union of value spaces and lexical spaces of two or more other data types. A union data type enables an element or attribute value to be one or more instances of a type drawn from the union or combination of multiple atomic and list types. Union types have a memberTypes attribute value that is a list of all the types in the union. Union types can have pattern and enumeration facets.


Anonymous and Named Data Types

Data types can be either anonymous or named. Named types allow you to use the type in other parts of the schema.

Anonymous Data Types

Anonymous data types are referenced only once and contain few constraints. These data types are identified by the lack of a type identifier in the element. The use of anonymous types saves the overhead of naming and explicitly referencing elements.

Named Types and Anonymous Types

Simple and custom types can be named so that they can be reused in other places in the schema. Anonymous types are used only within the element in which the definition appears. You are not required to name every custom type that you create. You can omit the cross reference between the element and type for types that are used once for an element.


Parts of Data Types

[This is preliminary documentation and subject to change.]

Data types consist of three parts.

  • value space
  • lexical space
  • facets (fundamental or constraining)

Value space

Value space refers to a set of literal values. Derived types inherit their value space from the base type; derived types are restricted by their base types.

Lexical space

Lexical space refers to the representation of literal values. Lexical space is the set of string literals that represent the values of data types. These literals always consist of text characters from any XML-legal subset of Unicode character set.

Facets

Facets are properties of the value space. A facet is one of the defining properties of a data type that distinguishes it from other data types. The Worldwide Web Consortium (W3C) defines a facet as a single defining aspect of a value space. Facets provide definition for simple types. A facet is a restriction to a data type.

Facets of a data type serve to distinguish aspects of one data type that differ from other data types. There are two types of facets: fundamental facets and nonfundamental (constraining) facets. Fundamental facets define the data type. Nonfundamental or constraining facets place constraints or restrictions on the data type.

Fundamental Facets

There are five fundamental facets.

Equality
Different values can be compared and determined to be equal or not.
Order
For some data types, defined relationships exist between values.
Bounds
Order data types may be constrained to a range of values.
Cardinality
The number of values within the value space.
Numeric/nonnumeric

Constraining Facets

Constraining facets limit the values of a derived data type.

There are several constraining facets that can be applied to a derived data type.

Facets that deal with length (length, minLength, maxLength)
Facets that deal with lexical space (pattern)
Enumeration
minExclusive, maxExclusive, minInclusive, maxInclusive
Precision, scale
Encoding
Duration, period


Schema Structures

[This is preliminary documentation and subject to change.]

Schema structures define and describe a class of XML documents. Schemas may also provide for the specification of additional document information, such as normalization and defaulting of attribute and element values.

Any application that consumes well-formed XML can use the World Wide Web (W3C) XML Schema: Structures specification to create and describe structures and constraints for XML documents.

Because schemas have the ability for self-documentation, they can be used to define, describe, and categorize XML vocabularies for classes of XML documents.

Structures allow you to describe content models for schemas.

This section covers the following topics.

Definitions and Declarations

Data Type Definitions

Declaring Attributes

Declaring Elements

Defining Complex Types

Content Models

Notation Declarations

Using Content from Other Schemas

Documenting Schemas

Using Other Namespaces


Definitions and Declarations

There are two different types of markup in XML schemas that correspond to two parts of the specification: definitions and declarations.

Definitions create new types (simple and complex types).

Declarations describe the content models of elements and attributes. Declarations are an association between a name and the set of constraints for the specific declaration. The declarations are not types. There is a separate definition that specifies the nature of that type within the declaration.

An element whose content is a simple type can be defined in one element (such as Invoice) while elements with complex types must first be declared with two attributes, name and type. The name attribute is the name of the element; the type attribute is used to associate name with its type definition. It is the type definition that defines the content model for that type which any other element can also use. The complex type is defined as an element called complexType. It is also possible to nest the complexType element in the element declaration if it only applies to that one element, in which case the type attribute is not needed.

There are two kinds of type declarations that are used to create structures: simple declarations and complex declarations.

Simple Declarations

Simple declarations create simple types. You can create derived data types from base types. These derived types are created from types that are built into the XML Schema specification or from types that are based from another simple type.

Complex Declarations

Complex declarations create complex types. Complex types are used to describe the content model.


Data Type Definitions

[This is preliminary documentation and subject to change.]

Data type definitions are created from another base type using either extension or restriction.

Simple type definitions describe the content.

Complex type definitions describe the structure or the content model of the XML document.

The following can be complex data types:

  • elements that contain other elements.
  • elements that contain both elements and text.
  • elements that contain only text.
  • elements that are empty.

This section includes the following topics.

Ur-Type Definitions

Simple Type Definitions

Complex Type Definitions


Ur-Type Definitions

[This is preliminary documentation and subject to change.]

The set of type definitions for a schema form a hierarchical tree with a single root known as the Type Definition Hierarchy. The root of this tree is called a ur-type definition. The ur-type definition is unique because it can be used as a complex type or a simple type, depending on the context of the definition.

Ur-types are unconstrained. They are the base type for all simple and complex types.


Simple Type Definitions

[This is preliminary documentation and subject to change.]

A simple type definition is a set of constraints on the value space and lexical space of a data type. Constraints are in the form of a restriction on the base type or the specification of a list type that is constrained by another simple type definition.

Simple type definitions are for all the built-in primitive and derived data types that are present in schemas.

A simple type definition is a set of constraints on strings and information about their values. This applies to values of attribute elements or element elements that have no child elements. It applies to attribute values and text-only content of elements.

A simple type definition uses the simpleType element, attributes, and valid constraining facets.

Each simple type definition (built-in or derived) is a restriction of some particular simple base type definition. For built-in simple types, this is the simple version ur-type definition, anySimpleType, which is understood to be a restriction of the ur-type definition. Simple types may also be defined whose members are lists of items themselves constrained by some other simple type definition.

Deriving Simple Types Using Restriction

New simple types can be defined using restriction.

Example

The following example shows a simple type definition that is created using a restriction base. The restriction element constrains the values of the simple type definition to values that are positive integers, as defined by the W3C Datatypes specification. These values must also be under 100, as indicated by the maxExclusive element.

<xsd:simpleType>
   <xsd:restriction base="xsd:positiveInteger">
     <xsd:maxExclusive value="100"/>
    </xsd:restriction>
</xsd:simpleType>

Deriving Simple Types Using List

New simple types can be defined using list. Data types derived by list contain a white space-delimited list of values that conform to the base type. A list data type must be derived from an atomic data type.

Example

The following example shows a simple unbounded list of floating-point numbers.

<xsd:simpleType name="decimalsList" base="xsi=decimal" derivedBy="list"/>

Example

The following example shows an acceptable use of the decimalsList data type in complying XML documents.

<decimalsList>-2.0 -3.0 8.6</decimalsList>


Complex Type Definitions

[This is preliminary documentation and subject to change.]

New complex types are defined using the complexType element. These definitions usually contain a set of element declarations, element references, and attribute declarations.

A complex type definition is a set of attribute declarations and content type that apply to the attributes and children of an element information item. Each complex type definition is either a restriction of a complex base type definition or an extension of a simple or complex base type definition or a restriction of the ur-type definition.

A complex type that extends another does so by having additional content model particles at the end of the other type definition's content model, or by having additional attribute declarations, or both.

Example

The following example shows a complex type definition for USAddress.

<xsd:complexType name="USAddress">
   <xsd:sequence>
      <xsd:element name="name" type="xsd:string"/>
      <xsd:element name="street" type="xsd:string"/>
      <xsd:element name="city" type="xsd:string"/>
      <xsd:element name="state" type="xsd:string"/>
      <xsd:element name="zip" type="xsd:decimal"/>
   </xsd:sequence>
   <xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType>

See Also

Declaring Attributes | Declaring Elements


Declaring Attributes

[This is preliminary documentation and subject to change.]

Attributes are declared using the attribute element.

Example

The following example shows an attribute declaration for blue.

<xsd:attribute name="blue" />

Referencing a Global Attribute Declaration

You can define attributes globally and use the ref attribute to reference global attributes.

Example

The following example shows a reference to the global attribute, blue.

<xsd:element name="eyeColor" type="eyeColorType" />
<xsd:complexType name="eyeColorType">
   <xsd:attribute ref="blue" />
   <xsd:attribute name="light" />
</xsd:complexType>

Example

The following example shows another reference to the global attribute, blue.

<xsd:element name="contactLense" type="contactLenseType" />
<xsd:complexType name="ContactLenseType" />
   <xsd:attribute ref="blue" />
</xsd:complexType>


Declaring Elements

[This is preliminary documentation and subject to change.]

Elements are declared using the element element.

Example

The following example shows an element declaration for Software.

<xsd:element name="Software" />

Referencing a Global Element Declaration

If you declare the complex type for this element at the top of the document (global declaration), you can reference this element in the remainder of the schema using the ref attribute.

Example

The following example shows an element declaration for Software element.

<xsd:element name="Software" />
   <xsd:complexType>
      <xsd:element name="title" />
      <xsd:element name="company" />
   </xsd:complexType>
</xsd:element>

The following example shows a reference to the global element declaration for the Software element.

<xsd:element name="Catalog">
<xsd:complexType>
      <xsd:element ref="Software">
</xsd:complexType>
</xsd:element>

Elements without a type defined will take a ur-type definition.

See Also

Ur-Type Definitions


Defining Complex Types

[This is preliminary documentation and subject to change.]

Definitions of complex types are created using the complexType element, its attributes, and any valid facets. Usually, complex types will contain a set of element declarations, attribute declarations, and element references.

Example

The following example creates a complex type definition for the Client element to describe the content model.

<xsd:element name="Client">
   <xsd:complexType name="ClientType">
      <xsd:attribute name="CompanyName" type="string"/>
      <xsd:attribute name="City" type="string"/>
      <xsd:attribute name="State" type="string"/>
   </xsd:complexType>
</xsd:element>

See Also

Content Models


Content Models

[This is preliminary documentation and subject to change.]

A content model is the formal description of the structure and allowable content of an element that is used to validate an XML document. Schema content models offer more control on element occurrences than DTD content models. In addition, schema content models allow the validation of mixed content.

A content model can restrict a document to a certain set of element types and attributes, describe and constrain the relationships between these different components, and uniquely identify specific elements. Sharing a content model allows businesses to exchange structured information.

This section includes the following topics.

Groups

Named Model Groups

Attribute Groups


Groups

[This is preliminary documentation and subject to change.]

There are three group elements: choice, sequence, and all.

group element

The group element groups a set of element declarations so that they can be incorporated into complex type definitions. The group element is limited to the top level of the content model.

choice element

The choice element allows one and only one of the elements contained in the group to be present within the containing element.

sequence element

The sequence element requires the element in the group to appear in the specified sequence within the containing element.

all element

The all element allows the elements in the group to appear (or not appear) in any order in the containing element.


Named Model Groups

[This is preliminary documentation and subject to change.]

The group element is used both for the definition of a group and any reference to a named group. You can use a model group to define a set of elements that can be repeated through the document. This is useful for building a complex type definition. Named model groups can be further defined by using sequence, choice, all, or group child elements.

A named model group consists of element declarations, wildcards, and other model groups. Named model groups use the group element and must be declared at the top level of the schema.

If you do not use the group element, the content model is an unnamed group.

Example

The following example creates a named model group, books, to allow a limited set of 1-5 books to appear in the group.

<xsd:group name="books">
   <xsd:sequence>
      <xsd:element name="books" minOccurs="1" maxOccurs="5" />
   </xsd:sequence>
</xsd:group>

Referencing a Global Group Declaration

You can use the ref attribute to reference the group by name to use the group description.

Example

The following example references a model group, books, inside of the choice element.

<xsd:element name="Order">
   <xsd:complexType>
…
      <xsd:choice>
         <xsd:element name="Customer" minOccurs="1" />
         <xsd:group ref="lineItems" minOccurs="1" maxOccurs="1" />
      </xsd:choice>
   </xsd:complexType>
</xsd:element>


Attribute Groups

[This is preliminary documentation and subject to change.]

Attribute groups are useful for grouping together attributes.

Example

The following example creates an attribute group, testMethods.

<xsd:attributeGroup name="testMethods" />
   <xsd:attribute name="writeVisualBasicCode" use="required" />
   <xsd:attribute name="blackbox" use="optional" />
   <xsd:attribute name="writeScriptCode" use="required" />
</xsd:attributeGroup>

Referencing a Global Attribute Group Declaration

If you want to reference the group of attributes for a full name on an element, you must add a reference to it using the ref attribute of the attributeGroup element.

Example

The following example references a global attribute group, testMethods.

<xsd:element name="testSuite">
   <xsd:complexType>
      <xsd:attributeGroup ref="testMethods" />
   </xsd:complexType>
</xsd:element>


Notation Declarations

[This is preliminary documentation and subject to change.]

Notation declarations associate a name with an identifier for a notation. The notation declarations are not validated. They are referenced when validating strings that are members of NOTATION simple type definitions are called in the XML document.

The public attribute of the notation element takes a public identifier from the ISO 8879 specification and system attribute takes a URI reference.

Example

The following example associates the jpeg file with a system executable, viewer.exe.

The content of this element would be a binary definition of the jpeg.

<xsd:notation name="jpeg" public="image/jpeg" system="viewer.exe" />
<xsd:element name="picture">
   <xsd:complexType>
      <xsd:complexContent>
         <xsd:extension base="xsd:binary">
            <xsd:attribute name="pictype" type="NOTATION" />
         </xsd:extension>
      </xsd:complexContent>
   </xsd:complexType>
</xsd:element>

The following example shows an element, picture, in an XML document.

<picture pictype="jpeg">…</picture>


Using Content from Other Schemas

[This is preliminary documentation and subject to change.]

The any element is used to add an element from another namespace to the schema. It allows any element from the specified namespace(s) to appear in the containing schema. The content of the any element can appear as a child element of complexType, group, sequence, all, or choice elements.

Example

The following example allows catalog element to contain any well-formed XML data that appears in the topbuyer catalog.

<xsd:element name="catalog">
   <xsd:complexType>
      <xsd:any namespace="http://www.topbuyer.com/catalog"
         minOccurs="0" maxOccurs="unbounded"
         processContents="skip" />
   </xsd:complexType>
</xsd:element>


Documenting Schemas

[This is preliminary documentation and subject to change.]

Because an XML schema is well-formed XML, you can include comments using XML comment syntax.

<!-- This is a comment -->

The XML parser does not pass comments to the application.

XML schema has three elements for schema meta data, for both application use and human readers.

Annotations allow you to make schemas self-documenting. By attaching a style sheet to the schema, you can create a readable version that explains the use of your schema.

Annotations

Annotations can appear anywhere in a schema to explain any element or attribute or type definition.

annotation element

The annotation element is the parent element for appInfo and documentation elements. This element can appear anywhere in the schema and allows you to document or comment on parts of your schema.

appInfo element

The appInfo element provides information for external applications, such as XML parsers. This element must be a child element of the annotation element.

documentation element

The documentation element allows you to place comments for human readers, such as copyright information, instructions about model group descriptions, and so on. This element must be child element of the annotation element.

Example

The following example shows an annotation that describes the purpose of the schema.

<xsd:schema xmlns="http://www.w3c.org/2001/XMLSchema">
   <xsd:annotation>
      <xsd:appInfo>Schema for processing submitted applications</appInfo>
      <xsd:documentation>
      Submitted applications for Human Resources department
      </xsd:documentation>
   </xsd:annotation>
…
</xsd:schema>

Example

The following example shows an annotation to explain the purpose and application use of the relocationStatus element.

<xsd:element name="relocationStatus">
   <xsd:complexType>
      <xsd:annotation>
         <xsd:appInfo>
         If relocationStatus is Seattle, no further processing for relocationStatus is required.
         </xsd:appInfo>
         <xsd:documentation>
         This element is for determining relocation status to determine help determine costs.
         </xsd:documentation>
      </xsd:annotation>
   </xsd:complexType>
</xsd:element>


Using Other Namespaces

[This is preliminary documentation and subject to change.]

The include element allows you to reference and use schema components from external namespaces so that you do not have to redefine elements in every schema that requires the same existing content model or data type. It is possible to create new schemas that borrow or leverage from existing schemas.

Example

The following example shows the definitions and declarations from the humanresources.xsd schema are available to the containing schema through the use of the include element.

<xsd:schema
   xmlns="http://www.w3c.org/2001/XMLSchema"
   xmlns:xsd="http://www.w3c.org/2001/XMLSchema-datatypes"
   targetNamespace="http://www.example.com">
…
</xsd:schema>

<xsd:include xmlns:myschema="http://www.myschema.com/humanresources.xsd" />

Alternatively, if you want to merge data from documents marked up according to two schemas, you could create a schema that would validate a new XML document (XML document instances). In the instance of a document marked up according to this schema, you only need to declare this schema (not the included schema).

Multiple Schemas

Multiple schemas from the same target namespace can be nested. This is useful if you want to create new XML documents based on data coming from several sources.

Example

The following example shows a schema for cookbooks that includes the content models from the receipebooks schema. The recipebooks schema describes content models for desserts and wines.

<xsd:schema
xmlns="http://www.w3c.org/2001/XMLSchema"
targetNamespace="http://www.example.com/schemas/cookbooks">
<xsd:import schemaLocation=http://www.example.com/schemas/recipebooks.xsd />

   <xsd:element name="catalog" type="catalogType" />
   <xsd:complexType name="catalogType">
      <xsd:sequence>
         <xsd:element name="desserts" type="cookbooks:dessertsType" />
         <xsd:element name="wines" type="cookbooks:winesType" />
      </xsd:sequence>
   <xsd:attribute name="myISBN" type="cookbooks:ISBN" />
   </xsd:complexType>
</xsd:schema>


XML Schema Reference (XSD)

[This is preliminary documentation and subject to change.]

The XML Schema Definition (XSD) language enables you to define the structure and data types for XML documents. The World Wide Web Consortium (W3C) XML Schema Part 2: Datatypes is the specification for defining data types used in XML schemas. An XSD schema defines the elements, attributes, and data types that conform to the W3C XML Schema Part 1: Structures specification for the XML Schema Definition language. This reference is based on the W3C March 16, 2001 Working Draft for Datatypes and the W3C March 16, 2001 Working Draft for Structures.

Note The specification is not yet final and may change.

An XSD schema is composed of the top-level schema element. The schema element definition must include the following namespace:

http://www.w3.org/2001/XMLSchema

The schema element contains type definitions (simpleType element and complexType element) and attribute and element declarations.

XSD has built-in data types (such as integer, string, and so on) but also allows for the definition of new data types using the simpleType and complexType elements.

simpleType
A type definition for a value that can be used as the content (textOnly) of an element or attribute. This data type cannot contain elements or have attributes.
complexType
A type definition for elements that contain elements and attributes. This data type can contain elements and have attributes.

The element declarations in a schema define the elements (and their contents and attributes) that can appear and the rules for their appearance in an XML document that is an instance of that schema. An element declaration can contain either a simpleType or complexType element. An element can also be declared by referring to another element declaration (using the ref attribute), or to a simpleType or complexType (using the type attribute).

The element and attribute declarations can appear within the complexType element to constrain or restrict the content and attributes that can appear in elements of the named type. The minOccurs and maxOccurs attributes allow you to define the number of occurrences of an element in an instance document.

See Also

XML Schema Examples | XML Schema Element Map | XML Schema Elements | XML Data Types Reference | Primitive XML Data Types | Derived XML Data Types | Data Type Facets

Other Resources Other Resources

World Wide Web Consortium (W3C) XML Schema Part 2: Datatypes | World Wide Web Consortium (W3C) XML Schema Part 1: Structures


XML Schema Examples

[This is preliminary documentation and subject to change.]

This topic contains two example schemas.

Purchase Order Example

The following example shows a purchase order schema that defines a purchase order. This example shows the use of targetNamespace, element, and attribute declarations. This example also shows simpleType and complexType definitions.

<schema xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:po="http://electrocommerce.org/po"
        targetNamespace="http://electrocommerce.org/po">

<element name="purchaseOrder" type="po:PurchaseOrder"/>

 <element name="comment" type="string"/>

 <complexType name='Item'>
   <sequence>
    <element name="productName" type="string"/>
    <element name="quantity">
     <simpleType>
      <restriction base="positiveInteger">
        <maxExclusive value="100"/>
      </restriction>
     </simpleType>
    </element>
    <element name="price"    type="decimal"/>
    <element ref="po:comment"   minOccurs="0"/>
    <element name="shipDate" type="date" minOccurs='0'/>
   </sequence>
    <attribute name="partNum" type="po:Sku"/>
 </complexType>
 <complexType name="PurchaseOrder">
    <sequence>
      <element name="shipTo" type="po:Address"/>
      <element name="billTo" type="po:Address"/>
      <element ref="po:comment" minOccurs="0"/>
      <element name="items">
         <complexType>
           <sequence>
              <element name="item" minOccurs="0" maxOccurs="unbounded" type='po:Item'/>
            </sequence>
         </complexType>
       </element>
    </sequence>
<attribute name="orderDate" type="date"/>
 </complexType>
 <complexType name="Address">
  <sequence>
    <element name="name"   type="string"/>
    <element name="street" type="string"/>
    <element name="city"   type="string"/>
    <element name="state"  type="string"/>
    <element name="zip"    type="decimal"/>
   </sequence>
   <attribute name="country" type="NMTOKEN" fixed="US"/>
 </complexType>
 <simpleType name="Sku">
  <restriction base="string">
    <pattern value="/d{3}-[A-Z]{2}"/>
  </restriction>
 </simpleType>
</schema>

Mapping Schema Example

The following example shows a mapping schema for a DataSet that contains a relationship between the customer and orders tables in the Northwind database. Note the use of the additional namespace (urn:schemas-microsoft-com:xml-msdata) and the use of attributes from that namespace on the unique and element elements.

This schema also shows the use of identity constraints on elements (key, keyref, and unique). The key and keyref elements define a relationship between elements.

<?xml version="1.0" encoding="utf-8" ?>
<schema id="CustomersAndOrdersDataSet" targetNamespace="http://tempuri.org/myschema"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
xmlns:target="http://tempuri.org/myschema">
   <element name="Customer">
      <complexType>
         <sequence>
            <element name="CustomerID" type="string">
            </element>
            <element name="CompanyName" type="string">
            </element>
            <element name="ContactName" minOccurs="0" type="string">
            </element>
            <element name="ContactTitle" minOccurs="0" type="string">
            </element>
            <element name="Address" minOccurs="0" type="string">
            </element>
            <element name="City" minOccurs="0" type="string">
            </element>
            <element name="Region" minOccurs="0" type="string">
            </element>
            <element name="PostalCode" minOccurs="0" type="string">
            </element>
            <element name="Country" minOccurs="0" type="string">
            </element>
            <element name="Phone" minOccurs="0" type="string">
            </element>
            <element name="Fax" minOccurs="0" type="string">
            </element>
         </sequence>
      </complexType>
   </element>
   <element name="Order">
      <complexType>
         <sequence>
            <element name="OrderID" msdata:AutoIncrement="true" type="int">
            </element>
            <element name="CustomerID" minOccurs="0" type="string">
            </element>
            <element name="EmployeeID" minOccurs="0" type="int">
            </element>
            <element name="OrderDate" minOccurs="0" type="timeInstant">
            </element>
            <element name="RequiredDate" minOccurs="0" type="timeInstant">
            </element>
            <element name="ShippedDate" minOccurs="0" type="timeInstant">
            </element>
            <element name="ShipVia" minOccurs="0" type="int">
            </element>
            <element name="Freight" msdata:DataType="System.Currency" minOccurs="0" type="string">
            </element>
            <element name="ShipName" minOccurs="0" type="string">
            </element>
            <element name="ShipAddress" minOccurs="0" type="string">
            </element>
            <element name="ShipCity" minOccurs="0" type="string">
            </element>
            <element name="ShipRegion" minOccurs="0" type="string">
            </element>
            <element name="ShipPostalCode" minOccurs="0" type="string">
            </element>
            <element name="ShipCountry" minOccurs="0" type="string">
            </element>
         </sequence>
      </complexType>
   </element>
   <element name="CustomersAndOrders">
      <complexType>
         <sequence>
            <element ref="target:Customer" maxOccurs="unbounded" />
            <element ref="target:Order" maxOccurs="unbounded" />
         </sequence>
      </complexType>
      <key name="CustomerKey" msdata:PrimaryKey="true">
         <selector xpath="target:Customer" />
         <field xpath="target:CustomerID" />
      </key>
      <key name="OrdersKey" msdata:PrimaryKey="true">
         <selector xpath="target:Order" />
         <field xpath="target:OrderID" />
      </key>
      <keyref name="CustomersOrders" refer="target:CustomerKey">
         <selector xpath="target:Order" />
         <field xpath="target:CustomerID" />
      </keyref>
   </element>
</schema>

See Also

XML Schema Element Map | XML Schema Elements | XML Data Types Reference | Primitive XML Data Types | Derived XML Data Types | Data Type Facets


XML Schema Element Map

[This is preliminary documentation and subject to change.]

The following is the purchase order schema example shown in the previous topic. Click on the colored text for more information about a schema element.

See Also

XML Schema Examples


XML Schema Elements

[This is preliminary documentation and subject to change.]

The following table describes the XML Schema Definition (XSD) language elements.

all | Allows the elements in the group to appear (or not appear) in any order in the containing element.
any | Enables any element from the specified namespace(s) to appear in the containing complexType, sequence, all, or choice element.
anyAttribute | Enables any attribute from the specified namespace(s) to appear in the containing complexType element.
annotation | Defines an annotation.
appinfo | Specifies information to be used by applications within an annotation element.
attribute | Declares an attribute.
attributeGroup | Groups a set of attribute declarations so that they can be incorporated as a group into complex type definitions.
choice | Allows one and only one of the elements contained in the group to be present within the containing element.
complexContent | Contains extensions or restrictions on a complex type that contains mixed content or elements only.
complexType | Defines a complex type, which determines the set of attributes and the content of an element.
documentation | Specifies information to be read or used by users within the annotation element.
element | Declares an element.
extension | Contains extensions on complexContent or simpleContent, which can also extend a complex type.
field | Specifies an XML Path Language (XPath) expression that specifies the value (or one of the values) used to define an identity constraint (unique, key, and keyref elements).
group | Groups a set of element declarations so that they can be incorporated as a group into complex type definitions.
import | Identifies a namespace whose schema components are referenced by the containing schema.
include | Includes the specified schema document in the target namespace of the containing schema.
key | Specifies that an attribute or element value (or set of values) must be a key within the specified scope.
keyref | Specifies that an attribute or element value (or set of values) correspond with those of the specified key or unique element.
list | Defines a simpleType element as a list of values of a specified data type.
notation | Contains the definition of a notation.
redefine | Allows simple and complex types, groups, and attribute groups that are obtained from external schema files to be redefined in the current schema.
restriction (XSD) | Defines constraints on a simpleType, simpleContent, or complexContent definition.
schema | Contains the definition of a schema.
selector | Specifies an XPath expression that selects a set of elements for an identity constraint (unique, key, and keyref elements).
sequence | Requires the elements in the group to appear in the specified sequence within the containing element.
simpleContent | Contains either the extensions or restrictions on a complexType element with character data, or contains a simpleType element as content and contains no elements.
simpleType | Defines a simple type, which determines the constraints on and information about the values of attributes or elements with text-only content.
union | Defines a simpleType element as a collection of values from specified simple data types.
unique | Specifies that an attribute or element value (or a combinationof attribute or element values) must be unique within the specified scope.

See Also

XML Schema Element Map | XML Schema Reference (XSD) | XML Data Types Reference | Primitive XML Data Types | Derived XML Data Types | Data Type Facets


all Element

[This is preliminary documentation and subject to change.]

Allows the elements in the group to appear (or not appear) in any order in the containing element.

<all
    id = "ID"
    maxOccurs="1"
    minOccurs="0 | 1"
{any attributes with non-schema namespace…}
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
maxOccurs
The maximum number of times the element can occur. The value must be an integer greater than or equal to one.
minOccurs
The minimum number of times the element can occur. The value can be an integer equal to one. To specify that this element is optional, set this attribute to zero.

Element Information

Number of occurrences | One time within group; otherwise, unlimited.
Parent elements | group, extension, restriction, complexType
Contents | annotation, element

Example

The following example defines a complex data type containing an all element with three elements.

<xsd:element name="thing1" type="xsd:string"/>
<xsd:element name="thing2" type="xsd:string"/>
<xsd:element name="thing3" type="xsd:string"/>

<xsd:attribute name="myAttribute" type="xsd:decimal"/>

<xsd:complexType name="myComplexType">
 <xsd:all>
  <xsd:element ref="thing1"/>
  <xsd:element ref="thing2"/>
  <xsd:element ref="thing3"/>
 </xsd:all>
 <xsd:attribute ref="myAttribute"/>
</xsd:complexType>


any Element

[This is preliminary documentation and subject to change.]

Enables any element from the specified namespace(s) to appear in the containing complexType, group, sequence, all, or choice element.

<any
    id = "ID"
    maxOccurs="nonNegativeInteger | unbounded"
    minOccurs="nonNegativeInteger"
    namespace = "(##any | ##other) | list of {uriReference | (##targetNamespace |  ##local)}"
    processContents = "skip | lax | strict"
    {any attributes with non-schema namespace}
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
maxOccurs
The maximum number of times the element can occur on the element. The value can be an integer greater than or equal to zero. To set no limit on the maximum number, use the string "unbounded".
minOccurs
The minimum number of times the element can occur on the element. The value can be an integer greater than or equal to zero. To specify that this any group is optional, set this attribute to zero.
namespace
The namespaces containing the elements that can be used. If no namespace is specified, ##any is the default. If the namespace is specified, it must one of the following.

##any | Elements from any namespace can be present.
##other | Elements from any namespace that is not the target namespace of the parent element containing this element can be present.
##local | Elements that are not qualified with a namespace can be present.
##targetNamespace | Elements from the target namespace of the parent element containing this element can be present.
List of {URI references, ##targetNamespace, ##local} | Elements from a space-delimited list of the namespaces can be present. The list can contain the following: URI references of namespaces, ##targetNamespace, and ##local.

processContents
An indicator of how an application or XML processor should handle validation of XML documents against the elements specified by this any element. If no processContents attribute is specified, "strict" is the default. If processContents is specified, it must one of the following.

strict | The XML processor must obtain the schema for the required namespaces and validate any element from those namespaces.
lax | The XML processor attempts to obtain the schema for the required namespaces and validate any element from those namespaces; however, if the schema cannot be obtained, no errors will occur.
skip | The XML processor does not attempt to validate any elements from the specified namespaces.

Element Information

Number of occurrences | Unlimited
Parent elements | choice, sequence
Contents | annotation

Example

The following example shows an element declaration for an element that must contain one or more elements from the XHTML namespace with content processing set to "lax".

<xsd:element name='htmlText'>
  <xsd:complexType>
   <xsd:sequence>
     <xsd:any namespace='http://www.w3.org/1999/xhtml'
          minOccurs='1' maxOccurs='unbounded'
          processContents='lax'/>
   </xsd:sequence>
  </xsd:complexType>
</xsd:element>


anyAttribute Element

[This is preliminary documentation and subject to change.]

Enables any attribute from the specified namespace(s) to appear in the containing complexType element.

<anyAttribute
  id = "ID"
  namespace = "(##any | ##other) | list of {uriReference | (##targetNamespace |  ##local)}"
  processContents = "skip | lax | strict"
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
namespace
The namespaces containing the attributes that can be used. If no namespace is specified, "##any" is the default. If the namespace is specified, it must one of the following.

##any | Attributes from any namespace can be present.
##other | Attributes from any namespace that is not the target namespace of the parent element containing this anyAttribute element can be present.
##local | Attributes that are not qualified with a namespace can be present.
##targetNamespace | Attributes from the target namespace of the parent element containing this anyAttribute element can be present.
List of {URI references, ##targetNamespace, ##local} | Attributes from a space-delimited list of the namespaces can be present. The list can contain the following: URI references of namespaces, ##targetNamespace, and ##local.

processContents
An indicator of how an application or XML processor should handle validation of XML documents against the attributes specified by this anyAttribute element. If no processContents attribute is specified, "strict" is the default. If processContents is specified, it must one of the following.

strict | The XML processor must obtain the schema for the required namespaces and validate any attribute from those namespaces.
lax | The XML processor attempts to obtain the schema for the required namespaces and validate any attribute from those namespaces; however, if the schema cannot be obtained, no errors will occur.
skip | The XML processor does not attempt to validate any attributes from the specified namespaces.

Element Information

Number of occurrences | Unlimited
Parent elements | complexType, extension, restriction, attributeGroup
Contents | annotation

Example

The following example shows an element declaration for an element that contains a string and can have any attribute from the target namespace.

<xsd:element name="stringElementWithAnyAttribute">
   <xsd:complexType>
    <xsd:simpleContent>
      <xsd:extension base="string">
       <xsd:anyAttribute namespace="##targetNamespace"/>
      </xsd:extension>
    </xsd:simpleContent>
   </xsd:complexType>
</xsd:element>


annotation Element

[This is preliminary documentation and subject to change.]

Defines an annotation.

<annotation
id = "ID"
  {any attributes with non-schema namespace}
>

Element Information

Number of occurrences | One time in parent element.
Parent elements | Any element.
Contents | appinfo. documentation

Remarks

An annotation can contain appinfo elements (information to be used by applications) and documentation elements (comments or text to be read or used by users).

Example

The following example uses annotation and documentation elements to document a simple type and the enumerations that make up its definition.

<xsd:simpleType name="northwestStates">
    <xsd:annotation>
        <xsd:documentation>States in the Pacific Northwest of US
</xsd:documentation>
    </xsd:annotation>
  <xsd:restriction base="string">
    <xsd:enumeration value='WA'>
      <xsd:annotation>
        <xsd:documentation>Washington</xsd:documentation>
      </xsd:annotation>
    </xsd:enumeration>
    <xsd:enumeration value='OR'/>
      <xsd:annotation>
        <xsd:documentation>Oregon</xsd:documentation>
      </xsd:annotation>
    </xsd:enumeration>
    <xsd:enumeration value='ID'/>
      <xsd:annotation>
        <xsd:documentation>Idaho</xsd:documentation>
      </xsd:annotation>
    </xsd:enumeration>
  </xsd:restriction>
</xsd:simpleType>


appinfo Element

[This is preliminary documentation and subject to change.]

Specifies information to be used by applications within an annotation element.

<appinfo
  source = "uriReference"
>

Attributes

source
The source of the application information. The source must be a URI reference. Optional.

Element Information

Number of occurrences | Unlimited
Parent elements | annotation
Contents | Any well-formed XML content.

Remarks

Information supplied within the appinfo element is used by applications for processing instructions.

Example

The following example uses annotation, appinfo, and documentation elements to document a simple type and the enumerations that make up its definition.

<?xml version="1.0"?>
<xsd:schema targetNamespace="" xmlns="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="State">
    <xsd:annotation>
      <xsd:documentation>State Name</xsd:documentation>
      <xsd:appinfo>Application Information</xsd:appinfo>
    </xsd:annotation>
  </xsd:element>
</xsd:schema>


attribute Element (XSD)

[This is preliminary documentation and subject to change.]

Declares an attribute.

<attribute
  form = "qualified | unqualified"
  id = "ID"
  name = "NCName"
  ref = "QName"
  type = "QName"
  use = "{ default | fixed | optional | prohibited | required }"
  value = "string"
  {any attributes with non-schema namespace}
>
</attribute>

Attributes

form
The form for the attribute. The default value is the value of the attributeFormDefault attribute of the schema element containing the attribute. The value must be one of the following strings: "qualified" or "unqualified".

If the value is unqualified, this attribute is not required to be qualified with the namespace prefix.

If the value is qualified, this attribute must be qualified with the namespace prefix.

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
name
The name of the attribute. The name must be a no-colon-name (NCName) as defined in the XML Namespaces specification. Required if the containing element is the schema element. Name and ref attributes cannot both be present.

When an XML document is validated against a schema, each attribute in the document is validated against an attribute element in the schema. The attribute element with a name attribute that matches the local name of the attribute in the document is used to validate that attribute.

ref
The name of an attribute declared in this schema (or another schema indicated by the specified namespace). The ref value must be a qualified name (QName). The type can include a namespace prefix.

To declare an attribute using an existing attribute definition within a complex type, use the ref attribute to specify the existing attribute definition.

<xsd:attribute name="mybaseattribute">
  <xsd:simpleType>
   <xsd:restriction base="integer">
      <xsd:maxInclusive value="1000"/>
   </xsd:restriction>
  </xsd:simpleType>
</xsd:attribute>
<xsd:complexType name="myComplexType">
  <xsd:attribute ref="mybaseattribute"/>
</xsd:complexType name="myComplexType">
type
The name of a built-in data type or a simple type defined in this schema (or another schema indicated by the specified namespace). The type must be a QName. The type can include a namespace prefix.
use
An indicator of how the attribute is used. Optional.

If specified, this attribute must have one of the following values.

prohibited Attribute cannot be used.
optional Attribute is optional and may have any value. This is the default. The following are equivalent.
<xsd:attribute name="myattr" type="string"/>
<xsd:attribute name="myattr" type="string" use="optional"/>
Default Attribute has a default value.

If the attribute is not specified on an instance within an XML document, the attribute has the value specified in the value attribute.

<xsd:attribute name="myattr" type="string" use="default" value="test"/>

If the attribute is specified in an instance within an XML document, the attribute has the value given.
Fixed Attribute has a fixed value. The value specified in the value attribute must be the value for this attribute.

If the attribute is not specified on an instance within an XML document, the attribute has the value specified in the value attribute.

If the attribute is specified on an instance within an XML document, the attribute must have the value specified in the value attribute.

<xsd:attribute name="myattr" type="string" use="fixed" value="must be this value"/>
Required Attribute must appear once.

If the value attribute is specified, the attribute must have that value.

<xsd:attribute name="myattr" type="string" use="required" value="must appear and must be this value"/>

If value attribute is not specified, the attribute can have any value.

<xsd:attribute name="myattr" type="string" use="required" value="must appear but can have any value"/>

If the attribute is declared as global (its parent element is schema), this attribute is required on all elements in the schema.

value
The default value or fixed value for the attribute, depending on the use property. If this attribute is derived from another attribute, this specified value takes precedence over any default or fixed value provided on any inherited attribute. Optional.

Element Information

Number of occurrences | Number of attribute types specified in the schema.
Parent elements | attributeGroup, schema, complexType, restriction,.extension
Contents | annotation, simpleType

Remarks

An attribute declaration associates a name with a type definition, which can be a built-in data type or a simple type.

Attribute declarations can be present as child elements of the schema element (having global scope) or within complex type definitions. For complex types, attribute declarations can be present as local declarations or references to attributes with global scope.

Global attribute declarations must directly define simpleType elements.

In addition, attributes can appear by reference within attributeGroup and complexType elements.

Examples

In the following example, an attribute is declared by reference to a built-in type with a default value of "test" and used in a complexType element.

<xsd:attribute name="mybaseattribute" type="string" use="default" value="test"/>
<xsd:complexType name="myComplexType">
  <xsd:attribute ref="mybaseattribute"/>
<xsd:complexType name="myComplexType">

In the following example, a required attribute is declared directly within a complexType element.

<xsd:complexType name="myComplexType">
  <xsd:attribute name="mybaseattribute" type="string" use="required"/>
<xsd:complexType name="myComplexType">

In the following example, an attribute is declared by deriving from the built-in integer type (by restriction) and restricting the range of values to between "60" and "95", inclusive.

<xsd:attribute name="myHolidayLocationTemperature">
  <xsd:simpleType>
   <xsd:restriction base="integer">
    < xsd:minInclusive value="60"/>
    < xsd:maxInclusive value="95"/>
   </xsd:restriction>
  </xsd:simpleType>
</xsd:attribute>

In the following example, an attribute is declared as a list containing decimal values. (This allows an attribute such as shoeSizes="10.5 9 8 11" to contain a list of the values 10.5, 9, 8, and 11).

<xsd:attribute name="shoeSizes">
  <xsd:simpleType>
    <xsd:list itemType="decimal"/>
  </xsd:simpleType>
</xsd:attribute>

Other Resources Other Resources

W3C Namespaces in XML Recommendation


attributeGroup Element

[This is preliminary documentation and subject to change.]

Groups a set of attribute declarations so that they can be incorporated as a group for complex type definitions.

<attributeGroup
  id = "ID"
  name = "NCName"
  ref = "QName"
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
name
The name of the attribute group. The name must be a no-colon-name (NCName) as defined in the XML Namespaces specification. Required if the containing element is schema element; otherwise, name attribute is prohibited.
ref
The name of the attribute group whose attributes are included in an attributeGroup element or complexType element.

When a complexType element or attributeGroup element includes an attribute group, the name of the included attributeGroup element is used for the ref attribute.

This value must be a qualified name (QName).

Element Information

Number of occurrences | Unlimited
Parent elements | attributeGroup, complexType, schema
Contents | annotation

Remarks

An attribute group can be defined only as a child of the schema element. In this case, the name attribute must be present and contain the attribute, attributeGroup, or anyAttribute elements that make up the attribute group.

An attribute group can be included in an attributeGroup or complexType. In this case, the ref attribute must be present and the attributeGroup element must be empty. See the following example.

The attributeGroup elements can contain other attributeGroup elements.

Example

The following example shows an attribute group defined (myAttributeGroup) and used in a complex type (myElementType).

<xsd:attributeGroup name="myAttributeGroup">
    <xsd:attribute name="someattribute1" type="integer"/>
    <xsd:attribute name="someattribute2" type="string"/>
</xsd:attributeGroup>

<xsd:complexType name="myElementType">
    <xsd:attributeGroup ref="myAttributeGroup"/>
</xsd:complexType>

The following example shows two attribute groups defined (myAttributeGroupA and myAttributeGroupB) with one containing the other.

<xsd:attributeGroup name="myAttributeGroupA">
    <xsd:attribute name="someattribute10" type="integer"/>
    <xsd:attribute name="someattribute11" type="string"/>
</xsd:attributeGroup>

<xsd:attributeGroup name="myAttributeGroupB">
    <xsd:attribute name="someattribute20" type="date"/>
    <xsd:attributeGroup ref="myAttributeGroupA"/>
</xsd:attributeGroup>

Other Resources Other Resources

W3C Namespaces in XML Recommendation


choice Element

[This is preliminary documentation and subject to change.]

Allows one and only one of the elements contained in the group to be present within the containing element.

<choice
    id = "ID"
    maxOccurs="nonNegativeInteger | unbounded"
    minOccurs="nonNegativeInteger"
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
maxOccurs
The maximum number of times the choice can occur. The value can be an integer greater than or equal to zero. To set no limit on the maximum number, use the string "unbounded".
minOccurs
The minimum number of times the choice can occur. The value can be an integer greater than or equal to zero. To specify that this choice group is optional, set this attribute to zero.

Element Information

Number of occurrences | 1 within group and complexType elements; otherwise, unlimited.
Parent elements | group, choice, sequence, complexType, restriction, extension
Contents | annotation, any, choice, element, group, sequence

Example

The following complex type defines an element with one attribute and one and only one element from a choice of four specified elements.

<xsd:complexType name="chadState">
 <xsd:choice minOccurs="1" maxOccurs="1">
  <xsd:element ref="selected"/>
  <xsd:element ref="unselected"/>
  <xsd:element ref="dimpled"/>
  <xsd:element ref="perforated"/>
 </xsd:choice>
 <xsd:attribute name="candidate" type="candidateType"/>
</xsd:complexType>


complexContent Element

[This is preliminary documentation and subject to change.]

Contains extensions or restrictions on a complex type that contains mixed content or elements only.

<complexContent
  id = "ID"
  mixed = "boolean"
  {any attributes with non-schema namespace}
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
mixed
An indicator of whether character data is allowed to appear between the child elements of this complexType element. The default is false.

This mixed attribute can override the mixed attribute value specified on the containing complexType element.

Element Information

Number of occurrences | One time.
Parent elements | complexType
Contents | Optional—annotation Required—One and only one of the following elements: restriction, extension

Remarks

Complex content must be defined in one of the following ways.

restriction element | Restricts the contents of the complex type to a subset of those for inherited complex type.
extension element | Extends the complex type by adding attributes or elements.

Examples

The following example has a complex type, USAddress, that derives from another complex type, address, by extending the inherited type with two additional elements (state and zipcode).

<xsd:complexType name="address">
  <xsd:sequence>
   <xsd:element name="name"   type="string"/>
   <xsd:element name="street" type="string"/>
   <xsd:element name="city"   type="string"/>
  </xsd:sequence>
 </xsd:complexType>

 <xsd:complexType name="USAddress">
  <xsd:complexContent>
   <xsd:extension base="address">
    <xsd:sequence>
     <xsd:element name="state" type="USState"/>
     <xsd:element name="zipcode" type="positiveInteger"/>
    </xsd:sequence>
   </xsd:extension>
  </xsd:complexContent>
 </xsd:complexType>


complexType Element

[This is preliminary documentation and subject to change.]

Defines a complex type, which determines the set of attributes and the content of an element.

<complexType
  abstract = "boolean"
  base = "QName"
  block = "#all | subset of {extension, restriction}"
  final = "#all | subset of {extension, restriction}"
  id = "ID"
  mixed = "boolean"
  name ="NCName"
>

Attributes

abstract
An indicator of whether the complex type can be used in an instance document. If this value is true, an element cannot use this complex type directly but must use a complex type derived from this complex type. The default is false.
base
The name of a built-in data type, simple type, or complex type.

This complex type is derived from the type specified by the base value. The base value must be a qualified name (QName).

block
The type of derivation. The block attribute prevents a complex type that has the specified type of derivation from being used in place of this complex type. This value can contain #all or a list that is a subset of extension or restriction.

value | Description
extension | Prevents complex types derived by extension from being used in place of this complex type.
restriction | Prevents complex types derived by restriction from being used in place of this complex type.
#all | Prevents all derived complex types from being used in place of this complex type.

mixed
An indicator of whether character data is allowed to appear between the child elements of this complex type. The default is false.

If simpleContent element is a child element, the mixed attribute is not allowed.

If complexContent element is a child element, this mixed attribute can be overridden by the mixed attribute on the complexContent element.

final
The type of derivation. The final attribute prevents the specified type of derivation of this complexType element. This value can contain #all or a list that is a subset of extension or restriction.

Value | Description
extension | Prevents derivation by extension.
restriction | Prevents derivation by restriction.
#all | Prevents all derivation (both extension and restriction).

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
name
The name of the type. The name must be a no-colon-name (NCName) as defined in the XML Namespaces specification.

Required if the containing element is the schema element; otherwise, prohibited.

If specified, the name must be unique among all simpleType and complexType elements.

Element Information

Number of occurrences | Unlimited within schema; one time within element.
Parent elements | element, redefine, schema
Content | annotation, simpleContent, complexContent, group, all, choice, sequence, attribute, attributeGroup, anyAttribute

Remarks

A complex type is essentially a type definition for elements. An element can be declared with a type attribute that refers to a complexType element that defines the structure, content, and attributes of that element. (An element can also take a reference to a simpleType in its type attribute.)

A complex type can contain one and only one of the following elements, which determines the type of content allowed in the complex type.

Element | Description
simpleContent | The complex type has character data or a simpleType as content and contains no elements.
complexContent | The complex type contains only elements.
group | The complex type contains the elements defined in the referenced group.
sequence | The complex type contains the elements defined in the specified sequence.
choice | The complex type allows one of the elements specified in the choice element.
all | The complex type allows any or all of the elements specified in the all element to appear once.

If group, sequence, choice, or all is specified as the child element, the attributes for the complexType can be declared optionally using the following elements.

Element | Description
attribute | The complex type contains the specified attribute.
attributeGroup | The complex type contains the attributes defined in the referenced attributeGroup.
anyAttribute | The complex type can contain any attribute from the specified namespace(s).

Any number of attribute or attributeGroup elements can be used. One instance of anyAttribute can also be used.

If group, sequence, choice, or all is specified, the elements must appear in the following order.

  1. group | sequence | choice | all
  2. attribute | attributeGroup
  3. anyAttribute

Examples

The following example shows a complex type that contains a simple type (decimal) with an attribute and element declaration that uses that complex type.

<xsd:complexType name='internationalShoeSize'>
 <xsd:extension base='xsd:decimal'>
  <xsd:attribute name='sizing' type='xsd:string' />
 </xsd:extension>
</xsd:complexType>
<xsd:element name='myShoeSize' type='internationalShoeSize'/>

The following example shows an instance of the myShoeSize element within an XML document.

<myShoeSize sizing='UK'>10.5</myShoeSize>

The following example shows the myShoeSize element with the complexType defined anonymously within the element. (Note the absence of the name attribute.)

<xsd:element name='myShoeSize'>
 <xsd:complexType>
  <xsd:extension base='xsd:decimal'>
    <xsd:attribute name='sizing' type='xsd:string' />
   </xsd:extension>
 </xsd:complexType>
</xsd:element>

Other Resources Other Resources

W3C Namespaces in XML Recommendation


documentation Element

[This is preliminary documentation and subject to change.]

Specifies information to be read or used by users within an annotation element.

<documentation>
  source = "uriReference"
  xml:lang = "language"
</documentation>

Attributes

source
The source of the application information. The source must be a URI reference. Optional.
xml:lang
The indicator of the language used in the contents. Optional.

Element Information

Number of occurrences | Unlimited
Parent elements | annotation
Contents | Any well-formed XML content.

Remarks

Information supplied within the documentation element is not used in validation.

Example

For examples, see annotation Element.


element Element (XSD)

[This is preliminary documentation and subject to change.]

Declares an element.

<element
  abstract = "boolean"
  block = "#all or (possibly empty) subset of {substitution, extension, restriction}"
  default = "string"
  final = "#all or (possibly empty) subset of {extension, restriction}"
  fixed = "string"
  form = "qualified | unqualified"
  id = "ID"
  maxOccurs = "nonNegativeInteger | unbounded"
  minOccurs = "nonNegativeInteger"
  name = "NCName"
  nullable = "boolean"
  ref = "QName"
  substitutionGroup = "QName"
  type = "QName"
  {any attributes with non-schema namespace}
>

Attributes

abstract
An indicator of whether the element can be used in an instance document. If this value is true, the element cannot appear in the instance document. Instead, another element whose substitutionGroup attribute contains the qualified name (QName) of this element must appear in this element's place. More than one element can reference this element in its substitutionGroup attribute.

The default is false.

block
The type of derivation. The block attribute prevents an element that has the specified type of derivation from being used in place of this element. This value can contain #all or a list that is a subset of extension, restriction, or equivClass.

value | Description
extension | Prevents elements derived by extension from being used in place of this element.
restriction | Prevents elements derived by restriction from being used in place of this element.
substitution | Prevents elements derived by substitution from being used in place of this element.
#all | Prevents all derived elements from being used in place of this element.

default
The default value of the element if its content is a simple type or its content is textOnly.

The fixed and default attributes are mutually exclusive.

If the element contains a simple type, this value must be a valid value of that type.

substitutionGroup
The name of an element for which this element can be substituted. This element must have the same type or a type derived from the type of the specified element.

This value must be a QName.

Prohibited if the containing element is not the schema element.

final
The type of derivation. The final attribute sets the default value of the final attribute on the element element. This value can contain #all or a list that is a subset of extension or restriction.

Value | Description
extension | Prevents elements derived by extension from being used in place of this element.
restriction | Prevents elements derived by restriction from being used in place of this element.
#all | Prevents all derived elements from being used in place of this element.

Prohibited if the containing element is not the schema element.

fixed
The predetermined, unchangeable value of the element if its content is a simple type or its content is textOnly.

The fixed and default attributes are mutually exclusive.

form
The form for the element. The default value is the value of the elementFormDefault attribute of the schema element containing the attribute. The value must be one of the following strings: "qualified" or "unqualified".

If the value is unqualified, this attribute is not required to be qualified with the namespace prefix.

If the value is qualified, this attribute must be qualified with the namespace prefix.

Prohibited if the containing element is the schema element.

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
maxOccurs
The maximum number of times the element can occur within the containing element. The value can be an integer greater than or equal to zero. To set no limit on the maximum number, use the string "unbounded".

Prohibited if the containing element is the schema element.

minOccurs
The minimum number of times the element can occur within the containing element. The value can be an integer greater than or equal to zero. To specify that this element is optional, set this attribute to zero.

Prohibited if the containing element is the schema element.

name
The name of the element. The name must be a no-colon-name (NCName) as defined in the XML Namespaces specification.

Required if the containing element is the schema element.

nullable
The indicator of whether an explicit null value can be assigned to the element. This applies to element content and not the attributes of the element. The default is false.

If nullable is true, this enables an instance of the element to have the null attribute set to true. The null attribute is defined as part of the XML Schema namespace for instances.

For example, the following fragment defines a single element with nullable set to true.

<xsd:element name="myDate" type="xsd:date" nullable="true"/>

The following fragment uses that element and has an explicit null value (null attribute set to true).

<myDate xsi:null="true"></myNS:myDate>
ref
The name of an element declared in this schema (or another schema indicated by the specified namespace). The ref value must be a QName. The ref can include a namespace prefix.

Prohibited if the containing element is the schema element.

The type and ref attributes are mutually exclusive.

To declare an element using an existing element definition, use the ref attribute to specify the existing element definition.

<xsd:element ref="comment"/>
type
Either the name of a built-in data type, or the name of a simpleType or complexType element defined in this schema (or another schema indicated by the specified namespace). The supplied value must correspond to the name attribute on the simpleType or complexType element that is referenced.

The type and ref attributes are mutually exclusive.

To declare an element using an existing simple type or complex type definition, use the type attribute to specify the existing type.

<xsd:element name="name" type="xsd:string"/>

Element Information

Number of occurrences | Number of elements defined in the schema.
Parent elements | schema, choice, all, sequence, group
Contents | simpleType, complexType, key, keyref, unique

Remarks

An element declaration associates a name with a type definition, which can be a built-in data type, a simple type, or a complex type.

Element declarations can be present as child elements of the schema element (having global scope) or within complex type definitions. Within complex types, element declarations can be present as local declarations or references to elements with global scope.

Global element declarations must directly define complex types.

A simpleType or complexType element can be present as a child only if both the ref and type attributes are not present.

In addition, elements can appear by reference within choice, all, group, sequence, and complexType elements.

Examples

The following example contains two elements that can serve as substitutes for another element.

<xsd:element name="cat" type="string"/>
<xsd:element name="dog" type="string"/>
<xsd:element name="redDog" type="string"
    substitutionGroup="dog" />
<xsd:element name="brownDog" type="string"
    substitutionGroup ="dog" />

<xsd:element name="pets">
  <xsd:complexType>
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
      <xsd:element ref="cat"/>
      <xsd:element ref="dog"/>
    </xsd:choice>
  </xsd:complexType>
</xsd:element>

Other Resources Other Resources

W3C Namespaces in XML Recommendation | XML Schema Namespace for Instances


extension Element

[This is preliminary documentation and subject to change.]

Contains extensions on complexContent or simpleContent, which can also extend a complex type.

<extension
  base = "QName"
  id = "ID"
  {any attributes with non-schema namespace}
>

Attributes

base
The name of a built-in data type or simpleType element.

The element containing the extension element is derived from the simple type specified by the base value. The base value must be a qualified name (QName).

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.

Element Information

Number of occurrences | One time.
Parent elements | simpleContent, complexContent
Contents (simpleContent) | annotation, attribute, attributeGroup, anyAttribute
Contents (complexContent) | annotation, attribute, attributeGroup, anyAttribute, choice, all, sequence, group

Example

For examples, see simpleContent Element, complexContent Element, and complexType Element.


field Element

[This is preliminary documentation and subject to change.]

Specifies an XML Path Language (XPath) expression that specifies the value (or one of the values) used to define an identity constraint (unique, key, and keyref elements).

<field
  id = "ID"
  xpath="XPathExpression"
  {any attributes with non-schema namespace}
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
xpath
An XPath expression that is relative to each element selected by the selector of the identity constraint. This expression must identify a single element or attribute whose content or value is used for the constraint. If the expression identifies an element, that element must be of a simple type.

Element Information

Number of occurrences | One time.
Parent elements | key, keyref, unique
Contents | annotation

Remarks

An identity constraint must contain one or more field elements and those field elements must appear after the selector element.

Example

The following fragment is a field element that specifies the myID attribute as the field to use for the identity constraint.

<xsd:field xpath="@myID"/>


group Element (XSD)

[This is preliminary documentation and subject to change.]

Groups a set of element declarations so that they can be incorporated as a group into complex type definitions.

<group
  id = "ID"
  maxOccurs="{nonNegativeInteger | unbounded}"
  minOccurs="nonNegativeInteger"
  name="NCName"
  ref = "QName"
  {any attributes with non-schema namespace}
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
name
The name of the group. The name must be a no-colon-name (NCName) as defined in the XML Namespaces specification.

This attribute is used only when the schema element is the parent of this group element. In this case, the group is a "model" group to be used by complexType, choice, all, and sequence elements.

maxOccurs
The maximum number of times the group can occur. The value can be an integer greater than or equal to zero. To set no limit on the maximum number, use the string "unbounded".
minOccurs
The minimum number of times the group can occur. The value can be an integer greater than or equal to zero. To specify that the group is optional, set this attribute to zero.
ref
The name of a group defined in this schema (or another schema indicated by the specified namespace). The ref value must be a qualified name (QName). The type can include a namespace prefix.

To include a group in a complexType, use the ref attribute to specify the group to include.

Element Information

Number of occurrences | Unlimited
Parent elements | schema, choice, sequence, complexType, restriction, extension
Contents | annotation, all, choice, sequence

Remarks

Any one of the following elements can be a child of the group element.

choice | Permits one and only one of the elements contained in the group.
sequence | Requires the elements in the group to appear in the specified sequence.
all | Allows the elements in the group to appear (or not appear) in any order in the containing element.

The minOccurs and maxOccurs attributes have the default value "1." A group with neither attribute must appear once and only once in the containing element.

Example

The following example defines a group containing a sequence of three elements and uses the group element in a complex type definition.

<xsd:element name="thing1" type="xsd:string"/>
<xsd:element name="thing2" type="xsd:string"/>
<xsd:element name="thing3" type="xsd:string"/>

<xsd:attribute name="myAttribute" type="xsd:decimal"/>

<xsd:group name="myGroupOfThings">
 <xsd:sequence>
  <xsd:element ref="thing1"/>
  <xsd:element ref="thing2"/>
  <xsd:element ref="thing3"/>
 </xsd:sequence>
</xsd:group>

<xsd:complexType name="myComplexType">
  <xsd:group ref="myGroupOfThings"/>
  <xsd:attribute ref="myAttribute"/>
</xsd:complexType>

Other Resources Other Resources

W3C Namespaces in XML Recommendation


import Element

[This is preliminary documentation and subject to change.]

Identifies a namespace whose schema components are referenced by the containing schema.

<import
  id = "ID"
  namespace="uriReference"
  schemaLocation="uriReference"
  {any attributes with non-schema namespace}
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
namespace
The URI reference to the namespace to import.

The namespace attribute indicates that the containing schema document may contain qualified references to schema components in that namespace (through one or more prefixes declared with xmlns attributes).

If this attribute is absent, the containing schema can contain unqualified references to components in the imported namespace.

schemaLocation
The URI reference to the location of a schema document for the imported namespace.

If this attribute is absent, the author is allowing the identification of the schema for the imported namespace to be determined by the XML document that is an instance of the containing schema or the user or application that is processing it.

Element Information

Number of occurrences | Unlimited
Parent elements | schema
Contents | annotation

Remarks

The difference between the include element and the import element is that import element allows references to schema components from schema documents with different target namespaces and the include element adds the schema components from other schema documents that have the same target namespace (or no specified target namespace) to the containing schema. In short, the import element allows you to use schema components from any schema; the include element allows you to add all the components of an included schema to the containing schema.

See Also

include Element


include Element

[This is preliminary documentation and subject to change.]

Includes the specified schema document in the target namespace of the containing schema.

<include
  id = "ID"
  schemaLocation="uriReference"
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
schemaLocation
The URI reference to the location of a schema document to include in the target namespace of the containing schema.

Element Information

Number of occurrences | Unlimited
Parent elements | schema
Child elements | annotation

Remarks

The included schema document must meet one of the following conditions.

  • It must have the same target namespace as the containing schema document.
  • It must not have a target namespace specified (no targetNamespace attribute).

The import element allows references to schema components from schema documents with different target namespaces; the include element adds the schema components from other schema documents that have the same target namespace (or no specified target namespace) to the containing schema. In short, the import element allows you to use schema components from any schema; the include element allows you to add all the components of an included schema to the containing schema.

See Also

import Element


key Element

[This is preliminary documentation and subject to change.]

Specifies that an attribute or element value (or set of values) must be a key within the specified scope. The scope of a key is the containing element in an instance document. A key must be unique, nonnullable, and always present.

<key
    id = "ID"
    name="NCName"
    {any attributes with non-schema namespace}
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
name
The name of the key element. The name must be a no-colon-name (NCName) as defined in the XML Namespaces specification. Required.

The name must be unique within a schema.

Element Information

Number of occurrences | Unlimited
Parent elements | element
Contents | annotation , field, selector

Remarks

The key element must contain the following elements in order.

selector | The selector element contains an XML Path Language (XPath) expression specifying the set of elements across which the values specified by field must be unique. There must be one and only one selector element.
field | Each field element contains an XPath expression specifying the values (attribute or element values) that must be unique for the set of elements specified by the selector element. If there is more than one field element, the combination of the field elements must be unique. In this case, the values for a single field element may or may not be unique across the selected elements but the combination of all the fields must be unique. There must be one or more field element(s).

Example

For an example of key and keyref, see the mapping schema example in XML Schema Examples.

Other Resources Other Resources

W3C Namespaces in XML Recommendation


keyref Element

[This is preliminary documentation and subject to change.]

Specifies that an attribute or element value (or set of values) that correspond to those of the specified key or unique element.

<keyref
    id = "ID"
    name="NCName"
    refer = "QName"
    {any attributes with non-schema namespace}
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
name
The name of the keyref element. The name must be a no-colon-name (NCName) as defined in the XML Namespaces specification. Required.

The name must be unique within a schema.

refer
The name of a key or unique element defined in this schema (or another schema indicated by the specified namespace). The ref value must be a qualified name (QName). The type can include a namespace prefix. Required.

Element Information

Number of occurrences | One time.
Parent elements | element
Contents | annotation, field, selector

Remarks

The keyref element must contain the following elements in order.

selector | The selector element contains an XML Path Language (XPath) expression specifying the set of elements across which the values specified by field must be unique. There must be one and only one selector element.
field | Each field element contains an XPath expression specifying the values (attribute or element values) that must be unique for the set of elements specified by the selector element. If there is more than one field element, the combination of the field elements must be unique. In this case, the values for a single field element may or may not be unique across the selected elements but the combination of all the fields must be unique. There must be one or more field elements.

Example

For an example of key and keyref, see the mapping schema example in XML Schema Examples.

Other Resources Other Resources

W3C Namespaces in XML Recommendation


list Element

[This is preliminary documentation and subject to change.]

Defines a simpleType element as a list of values of a specified data type.

<list
  id = "ID"
  itemType = "QName"
  {any attributes with non-schema namespace}
>

Attributes

itemType
The name of a built-in data type or simpleType element defined in this schema (or another schema indicated by the specified namespace). The simpleType element containing the list element is derived from the simple type specified by the list value. The list value must be a qualified name (QName).
id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.

Element Information

Number of occurrences | One time.
Parent elements | simpleType
Child elements | annotation, simpleType

Remarks

When a data type is derived from a list data type, the following constraining facets can be used.

length

maxLength

minLength

enumeration

The unit of length is measured in the number of list items. For example, the following example sets the maxLength to "5", limiting the number of items in an instance of the derivedlistOfIntegers data type to 5.

<xsd:simpleType name='derivedlistOfIntegers'>
  <xsd:restriction base='listOfIntegers'>
    <xsd:maxLength value='5'>
  </xsd:restriction>
</xsd:simpleType>

Example

The following example shows a simpleType that is a list of integers.

<xsd:simpleType name='listOfIntegers'>
  <xsd:list itemType='integer'/>
</xsd:simpleType>

The following example shows an instance of an element that has an attribute of type listOfIntegers. Each item in the list is of type integer and is separated by white space—in this case, a space.

<myelement listOfIntegers='1 100 9 4000 0'>


notation Element

[This is preliminary documentation and subject to change.]

Contains the definition of a notation.

<notation
  id = "ID"
  name="NCName"
  public="public identifier per ISO 8879"
  system = "uriReference"
  {any attributes with non-schema namespace}
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
name
The name of the notation element. The name must be a no-colon-name (NCName) as defined in the XML Namespaces specification. Required.

The name must be unique within a schema.

public
A URI reference corresponding to the public attribute.
system
A URI reference corresponding to the system attribute. Optional.

Element Information

Number of occurrences | Unlimited.
Parent elements | schema
Contents | annotation

Other Resources Other Resources

W3C Namespaces in XML Recommendation


redefine Element

[This is preliminary documentation and subject to change.]

Allows simple and complex types, groups, and attribute groups that are obtained from external schema files to be redefined in the current schema.

<redefine
  schemaLocation = "uriReference"
  {any attributes with non-schema namespace}
>

Attributes

schemaLocation
A URI reference to the location of a schema document.

Element Information

Number of occurrences | Unlimited.
Parent elements | schema
Contents | annotation, attributeGroup, complexType, group, simpleType

Remarks

The redefine element requires that the external elements exist in the same target namespace as the redefining schema. Schemas without a namespace can also be redefined using the redefine element and the redefined components become part of the schema's target namespace.

The definitions within the redefine element itself must use their current definitions as the base type definition. Attribute group definitions and model group definitions must include exactly one reference to themselves. Not all of the definitions of the redefined schema document must be redefined.

Redefining elements can cause unexpected results, such as ill-formed definitions, on other type definitions that are based on the redefined definitions.

Example

The following example shows a schema, v2.xsd, with elements specified by the v1.xsd. The personName type is redefined. According to this schema, elements constrained by the personName type may end with a generation element.

v1.xsd:
 <xsd:complexType name="personName">
  <xsd:sequence>
   <xsd:element name="title" minOccurs="0"/>
   <xsd:element name="forename" minOccurs="0" maxOccurs="unbounded"/>
  </xsd:sequence>
 </xsd:complexType>

 <xsd:element name="addressee" type="personName"/>

v2.xsd:
 <xsd:redefine schemaLocation="v1.xsd">
  <xsd:complexType name="personName">
   <xsd:complexContent>
    <xsd:extension base="personName">
     <xsd:sequence>
      <xsd:element name="generation" minOccurs="0"/>
     </xsd:sequence>
    </xsd:extension>
   </xsd:complexContent>
  </xsd:complexType>
 </xsd:redefine>

 <xsd:element name="author" type="personName"/>


restriction Element

[This is preliminary documentation and subject to change.]

Defines constraints on a simpleType, simpleContent, or complexContent definition.

<restriction
  base = "QName"
  id = "ID"
  {any attributes with non-schema namespace}
>

Attributes

base
The name of a built-in data type, simpleType element, or complexType element defined in this schema (or another schema indicated by the specified namespace). The element containing the restriction element is derived from the type specified by the base value.

If the parent element containing the restriction is simpleType, base is the name of a built-in data type or simpleType element.

If the parent element containing the restriction is simpleContent, base is the name of a built-in data type, simple type, or complex type. If a complex type, this type must be of one of the following types: built-in data type, simple type, or simple content.

If the parent element containing the restriction is complexContent, base is the name of a complex type.

The base value must be a qualified name (QName).

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.

Element Information

Number of occurrences | One time.
Parent elements | simpleType, simpleContent, complexContent
Contents (simpleType) | annotation, simpleType, duration, encoding, enumeration, length, maxExclusive, maxInclusive, maxLength, minExclusive, minInclusive, minLength, pattern, period, precision, scale, whiteSpace
Contents (simpleContent) | Elements for simpleType contents, plus the following: attribute, attributeGroup, anyAttribute
Contents (complexContent) | group, all, choice, sequence, attribute, attributeGroup, anyAttribute

Example

The following example shows a simple type definition using restriction. (The simple type is derived from nonNegativeInteger and its maxInclusive value is set to "100".)

<xsd:simpleType name="freezeboilrangeInteger">
  <xsd:restriction base="xsd:nonNegativeInteger">
    <xsd:maxInclusive value="100"/>
  </xsd:restriction>
</xsd:simpleType>

Example

The following example shows a simple type definition that derives from the integer built-in type and has all the facets of integer (no restrictions).

<xsd:simpleType name="myInteger">
  <xsd:restriction base="xsd:integer"/>
</xsd:simpleType>

Example

The following example shows a simple type definition that derives from string and is an enumerated type. The set of values is restricted to specified values.

<xsd:simpleType name="mountainbikesize">
  <xsd:restriction base="xsd:string">
    <xsd:enumeration value="small"/>
    <xsd:enumeration value="medium"/>
    <xsd:enumeration value="large"/>
  </xsd:restriction>
</xsd:simpleType>

Example

The following example shows a complex type definition using restriction. The simple type is derived from positiveInteger and its maxExclusive value is set to "100".

<xsd:complexType>
      <xsd:sequence>
       <xsd:element name="productName" type="string"/>
       <xsd:element name="quantity">
        <xsd:simpleType>
         <xsd:restriction base="positiveInteger">
          <xsd:maxExclusive value="100"/>
         </xsd:restriction>
        </xsd:simpleType>
       </xsd:element>
       <xsd:element name="USPrice" type="decimal"/>
       <xsd:element ref="ipo:comment" minOccurs="0"/>
       <xsd:element name="shipDate" type="date" minOccurs="0"/>
      </xsd:sequence>
      <xsd:attribute name="partNum" type="ipo:SKU"/>
     </xsd:complexType>


schema Element (XSD)

[This is preliminary documentation and subject to change.]

Contains the definition of a schema.

<schema
  attributeFormDefault = "{ qualified | unqualified }"
  blockDefault = "#all or (possibly empty) subset of {substitution, extension, restriction}"
  elementFormDefault = "{ qualified | unqualified }"
  finalDefault = "#all or (possibly empty) subset of {extension, restriction}"
  id = "ID"
  targetNamespace = "uriReference"
  version = "string"
  xmlns="uriReference"
  {any attributes with non-schema namespace}
>

Attributes

xmlns
One or more namespaces for use in this schema. The xmlns must be a URI reference. A prefix for the namespace can also be assigned. If no prefix is assigned, the schema components of the namespace can be used with unqualified references.

In the following example, the schema components (element name, type) in the http://www.w3.org/2001/XMLSchema namespace are unqualified and those for http://tempuri.org/myschema (mydecimal) are qualified with the msc prefix.

<schema
     xmlns="http://www.w3.org/2001/XMLSchema"
     xmlns:msc="http://tempuri.org/myschema">
  <element name="Price" type="msc:mydecimal"/>
</schema>
attributeFormDefault
The form for attributes declared in the target namespace of this schema. The value must be one of the following strings: "qualified" or "unqualified". The default is unqualified.

If the value is unqualified, attributes from the target namespace are not required to be qualified with the namespace prefix.

If the value is qualified, attributes from the target namespace must be qualified with the namespace prefix.

This value is the global default for all attributes declared in the target namespace. Individual attributes can override this setting for their local scope using the form attribute.

elementFormDefault
The form for elements declared in the target namespace of this schema. The value must be one of the following strings: "qualified" or "unqualified". The default is unqualified.

If the value is unqualified, elements from the target namespace are not required to be qualified with the namespace prefix.

If the value is qualified, elements from the target namespace must be qualified with the namespace prefix.

This value is the global default for all elements declared in the target namespace. Individual elements can override this setting for their local scope using the form attribute.

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
blockDefault
The type of derivation. The blockDefault attribute sets the default value of the block attribute on element and complexType elements in the target namespace of this schema. The block attribute prevents a complex type (or element) that has the specified type of derivation from being used in place of the inherited complex type (or element). This value can contain #all or a list that is a subset of extension, restriction, or equivClass.

Value | Description
extension | Prevents complex types derived by extension from being used in place of this complex type.
restriction | Prevents complex types derived by restriction from being used in place of this complex type.
substitution | Prevents substitution of elements. (An element can declare itself a substitution for another element by specifying that other element's name in its substitutionGroup attribute.)
#all | Prevents all derived complex types from being used in place of this complex type.

finalDefault
The type of derivation. The finalDefault attribute sets the default value of the final attribute on element and complexType elements in the target namespace of this schema. The final attribute prevents the specified type of derivation of an element or complexType. This value can contain #all or a list that is a subset of extension or restriction.

Value | Description
extension | Prevents derivation by extension.
restriction | Prevents derivation by restriction.
#all | Prevents all derivation (both extension and restriction).

targetNamespace
The URI reference of the namespace of this schema. This is the namespace of all schema components in this schema as well as any schemas included using the include element. (Included schemas must have the same target namespace as the containing schema or have no target namespace at all.)
version
The version of the schema. Optional.

Element Information

Number of occurrences | One time.
Parent elements | (No parent elements.)
Content | include, import, annotation, redefine attribute, attributeGroup, element, group, notation, simpleType, complexType
Other | The include, import, and redefine elements must come before the other elements—except for annotation element which can appear anywhere.

Remarks

The schema element is the document element (the highest-level element) in a schema definition.

The namespaces specified using the xmlns attribute must include the namespace for the schema-defining elements and attributes (schema, element, and so on). Any prefix can be used, but it is convenient to make the "Schema" namespace the default namespace to avoid having to use a prefix on every XML Schema element.

For XSD, the namespace is the following.

http://www.w3.org/2000/10/XMLSchema

In addition, the schema element should also contain namespace declarations for any other schemas that it uses.

Example

The following schema uses the XSD namespace as the default namespace, uses the XSD data types namespace for data type definitions, and defines the schema's target namespace as http://mynamespace/myschema.

<schema xmlns="http://www.w3.org/2001/XMLSchema"
         targetNamespace="http://mynamespace/myschema">
  <!--Put schema content here  -->
</schema>

See Also

include Element


selector Element

[This is preliminary documentation and subject to change.]

Specifies an XML Path Language (XPath) expression that selects a set of elements for an identity constraint (unique, key, and keyref elements).

<selector
    id = "ID"
    xpath="XPathExpression"
    {any attributes with non-schema namespace}
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
xpath
An XPath expression that is relative to the element being declared. This expression identifies the child elements (of the element being declared) to which the identity constraint applies.

Element Information

Number of occurrences | One time.
Parent elements | key, keyref, unique
Contents | annotation

Example

The following fragment is a selector element that selects all expense elements with an approved attribute equal to true.

<selector xpath="//expense[@approved='true']"/>


sequence Element

[This is preliminary documentation and subject to change.]

Requires the elements in the group to appear in the specified sequence within the containing element.

<sequence
    id = "ID"
    maxOccurs="nonNegativeInteger | unbounded"
    minOccurs="nonNegativeInteger"
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
maxOccurs
The maximum number of times the sequence can occur. The value can be an integer greater than or equal to zero. To set no limit on the maximum number, use the string "unbounded".
minOccurs
The minimum number of times the sequence can occur. The value can be an integer greater than or equal to zero. To specify that this sequence group is optional, set this attribute to zero.

Element Information

Number of occurrences | One time within group; otherwise, unlimited.
Parent elements | group, choice, sequence, complexType, restriction,.extension
Contents | annotation, any, choice, element, group, sequence

Example

The following example shows an element (zooAnimals) that can have zero or more of the following elements, elephant, bear, giraffe, in the sequence element.

<xsd:element name="zooAnimals">
      <xsd:complexType>
            <xsd:sequence minOccurs="0" maxOccurs="unbounded">
               <xsd:element name="elephant"/>
               <xsd:element name="bear"/>
               <xsd:element name="giraffe"/>
            </xsd:sequence>
      </xsd:complexType>
   </xsd:element>


simpleContent Element

[This is preliminary documentation and subject to change.]

Contains either the extensions or restrictions on a complexType element with character data, or contains a simpleType element as content and contains no elements

<simpleContent
  id = "ID"
  {any attributes with non-schema namespace}
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.

Element Information

Number of occurrences | One time.
Parent elements | complexType
Contents | Optional—annotation Required—One and only one of the following elements:restriction, extension

Remarks

The simpleContent element enables you to specify an element as containing a simpleType with no elements but enables you to restrict the value of the element's content or extend the element with attributes. For example, the following element declaration does not allow for adding attributes (such as sizing).

<xsd:element name="shoeSize" type="decimal"/>

Example

Using the simpleContent element, the following element declaration contains a complexType element that defines the content of the element as a decimal type with a single attribute (sizing).

<xsd:element name="shoeSize">
  <xsd:complexType>
    <xsd:simpleContent>
      <xsd:extension base="xsd:decimal">
        <xsd:attribute name="sizing">
          <xsd:restriction base="xsd:string">
            <xsd:enumeration value="US"/>
            <xsd:enumeration value="European"/>
            <xsd:enumeration value="UK"/>
            <xsd:enumeration value="Japan"/>
          </xsd:restriction>
        </xsd:attribute>
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>
</xsd:element>

Simple content must be defined in one of the following ways.

restriction element | Restricts the range of values for the element to a subset of those for inherited simpleType.
extension element | Extends the simpleType content of the element by adding attributes.

Examples

The following example shows an element (generalPrice) declared using an anonymous complexType (one without a name) with its content defined as a decimal data type and with a currency attribute.

<xsd:element name="generalPrice">
  <xsd:complexType>
    <xsd:simpleContent>
      <xsd:extension base="xsd:decimal">
        <xsd:attribute name="currency" type="xsd:string" />
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>
</xsd:element>


simpleType Element

[This is preliminary documentation and subject to change.]

Defines a simple type, which determines the constraints on and information about the values of attributes or elements with text-only content.

<simpleType
  id = "ID"
  name="NCName"
  {any attributes with non-schema namespace}
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
name
The name of the type. The name must be a no-colon-name (NCName) as defined in the XML Namespaces specification. Optional.

If specified, the name must be unique among all simpleType and complexType elements.

Element Information

Number of occurrences | Unlimited
Parent elements | attribute, element, list, restriction, schema, union
Contents | annotation, list, restriction, union

Remarks

Simple types are defined by deriving them from existing simple types (built-in data types and derived simple types). A simple type cannot contain elements and cannot have attributes.

Simple types can be defined in one of the following ways.

restriction | Restricts the range of values for the simple type to a subset of those for inherited simple type.
list | Defines a simple type that contains a white space-separated list of values of an inherited simple type.
union | Defines a simple type that contains a union of the values of two or more inherited simple types.

A simpleType declaration contained within a complexType or attribute element defines that simple type within the scope of the complexType or attribute that contains it. If a simpleType declaration has the schema element as its parent, it has global scope within that schema.

After a simple type is defined, it can be used in an attribute or element declaration or complexType (which, in turn, can be used in an element declaration) definition.

Examples

The following examples show simple type definitions using restriction, list, and union elements.

Restriction

<xsd:simpleType name="freezeboilrangeInteger">
  <xsd:restriction base="xsd:integer">
    <xsd:minInclusive value="0"/>
    <xsd:maxInclusive value="100"/>
  </xsd:restriction>
</xsd:simpleType>

List

<xsd:simpleType name="listOfDates">
  <xsd:list itemType="date">
</xsd:simpleType>

Union

<xsd:attribute name="allframesize">
  <xsd:simpleType>
    <xsd:union>
      <xsd:simpleType>
        <xsd:restriction base="roadbikesize"/>
      </xsd:simpleType>
      <xsd:simpleType>
        <xsd:restriction base="mountainbikesize"/>
      </xsd:simpleType>
    </xsd:union>
  </xsd:simpleType>
</xsd:attribute>

<xsd:simpleType name="roadbikesize">
  <xsd:restriction base="xsd:positiveInteger">
    <xsd:enumeration="46"/>
    <xsd:enumeration="52"/>
    <xsd:enumeration="55"/>
  </xsd:restriction>
</xsd:simpleType>

<xsd:simpleType name="mountainbikesize">
  <xsd:restriction base="xsd:string">
    <xsd:enumeration value="small"/>
    <xsd:enumeration value="medium"/>
    <xsd:enumeration value="large"/>
  </xsd:restriction>
</xsd:simpleType>

Other Resources Other Resources

W3C Namespaces in XML Recommendation


union Element

[This is preliminary documentation and subject to change.]

Defines a simpletype element as a collection of values from specified simple data types.

<union
  id = "ID"
  memberTypes = "List of QNames"
  {any attributes with non-schema namespace}
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
memberTypes
The list of names of built-in data types or simpleType elements defined in this schema (or another schema indicated by the specified namespace). The simpleType element containing the union element is derived from the simple types specified by the memberTypes value. The values in memberTypes must be qualified names (QNames).

Element Information

Number of occurrences | One time.
Parent elements | simpleType
Contents | annotation, simpleType

Example

The following example shows a simple type that is a union of two simple types.

<xsd:attribute name="fontsize">
  <xsd:simpleType>
    <xsd:union memberTypes="fontbynumber fontbystringname" />
  </xsd:simpleType>
</xsd:attribute>

<xsd:simpleType name="fontbynumber">
  <xsd:restriction base="xsd:positiveInteger">
    <xsd:maxInclusive="72"/>
  </xsd:restriction>
</xsd:simpleType>

<xsd:simpleType name="fontbystringname">
  <xsd:restriction base="xsd:string">
    <xsd:enumeration value="small"/>
    <xsd:enumeration value="medium"/>
    <xsd:enumeration value="large"/>
  </xsd:restriction>
</xsd:simpleType>

Example

The following example shows a simple type definition that is a union of all nonnegative integers and the NMTOKEN "unbounded". (This is from the schema in the W3C XML Schema Part 1: Structures specification.)

<xsd:simpleType name="allNNI">
  <xsd:annotation>
    <xsd:documentation>for maxOccurs</documentation>
  </xsd:annotation>
  <xsd:union memberTypes="nonNegativeInteger">
   <xsd:simpleType>
    <xsd:restriction base="NMTOKEN">
     <xsd:enumeration value="unbounded"/>
    </xsd:restriction>
   </xsd:simpleType>
  </xsd:union>
 </xsd:simpleType>

Other Resources Other Resources

World Wide Web Consortium (W3C) XML Schema Part 1: Structures


unique Element

[This is preliminary documentation and subject to change.]

Specifies that an attribute or element value (or a combination of attribute or element values) must be unique within the specified scope.

<unique
    id = "ID"
    name="NCName"
    {any attributes with non-schema namespace}
>

Attributes

id
The ID of this element. The id value must be of type ID and be unique within the document containing this element. Optional.
name
The name of the unique element. The name must be a no-colon-name (NCName) as defined in the XML Namespaces specification. Required.

The name must be unique within a schema.

Element Information

Number of occurrences | One time.
Parent elements | element
Contents | annotation, field, selector

Remarks

The unique element must contain the following elements in order.

selector | The selector element contains an XML Path Language (XPath) expression specifying the set of elements across which the values specified by the field elements must be unique. There must be one and only one selector element.
field | Each field element contains an XPath expression specifying the values (attribute or element values) that must be unique for the set of elements specified by the selector element. If there is more than one field element, the combination of the field elements must be unique. In this case, the values for a single field element may or may not be unique across the selected elements, but the combination of all the fields must be unique. There must be one or more field element.

Example

The following example defines a schema with a root element of ordersByCustomer, which can contain an unbounded sequence of customerOrders elements. In the ordersByCustomer element, the unique element specifies that the customerID attribute must be unique across all customerOrders.

<xsd:schema targetNamespace="http://tempuri.org/myschema/unique">
<xsd:complexType name="customerOrderType">
 <xsd:sequence>
  <xsd:element name="item" minOccurs="0" maxOccurs="unbounded">
    <xsd:complexType>
    <xsd:attribute name="itemID" type="string"/>
    </xsd:complexType>
  </xsd:element>
 </xsd:sequence>
 <xsd:attribute name="CustomerID" type="string"/>
</xsd:complexType>

<xsd:element name="ordersByCustomer">
 <xsd:complexType>
    <xsd:sequence>
     <xsd:element name="customerOrders" type="customerOrderType" minOccurs="0" maxOccurs="unbounded" />
    </xsd:sequence>
 </xsd:complexType>
 <xsd:unique name="oneCustomerOrdersforEachCustomerID">
  <xsd:selector xpath="customerOrders"/>
  <xsd:field xpath="@customerID"/>
 </xsd:unique>
</xsd:element>
</xsd:schema>

Other Resources Other Resources

W3C Namespaces in XML Recommendation


XML Data Types Reference

[This is preliminary documentation and subject to change.]

The World Wide Web Consortium (W3C) XML Schema Part 2: DataTypes is the specification for defining data types used in XML Schemas. This specification defines built-in primitive data types, derived data types, and facets.

See Also

Primitive XML Data Types| Derived XML Data Types | Data Type Facets

Other Resources Other Resources

World Wide Web Consortium (W3C) XML Schema Part 2: Datatypes


Primitive XML Data Types

[This is preliminary documentation and subject to change.]

The following table lists primitive XML schema data types, facets that can be applied to the data type, and a description of the data type.

Data Type | Facets | Description
string | length , pattern, maxLength, minLength, enumeration, whiteSpace | Represents character strings.
Boolean | pattern, whiteSpace | Represents Boolean values, which are either true or false.
float | pattern, enumeration, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents single-precision 32-bit floating point numbers.
double | pattern, enumeration, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents double-precision 64-bit floating point numbers.
decimal | enumeration, pattern, scale, precision, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents arbitrary precision numbers.
timeDuration | enumeration, pattern, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents a duration of time.
recurringDuration | period, duration, enumeration, pattern, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents a timeDuration that recurs at a specific timeDuration, starting from a specific origin. This data type cannot be used directly in a schema. Only derived data types that specify duration and period can be used.
binary | encoding, length, pattern, maxLength, minLength, enumeration, whiteSpace | Represents binary data. This data type cannot be used directly in a schema. Only derived data types that specify encoding can be used.
uriReference | length, pattern, maxLength, minLength, enumeration, whiteSpace | Represents a Uniform Resource Identifier (URI) as defined by RFC 2396.
ID | length, enumeration, pattern, maxLength, minInclusive, minExclusive, maxInclusive, maxExclusive, minLength, whiteSpace | Represents the ID attribute type defined in the XML 1.0 Recommendation. The ID must be a no-colon-name (NCName) and must be unique within an XML document.
IDREF | length, enumeration, pattern, maxLength, minInclusive, minExclusive, maxInclusive, maxExclusive, minLength, whiteSpace | Represents a reference to an element that has an ID attribute that matches the specified ID. An IDREF must be an NCName and must be a value of an element or attribute of type ID within the XML document.
ENTITY | length, enumeration, pattern, maxLength, minInclusive, minExclusive, maxInclusive, maxExclusive, minLength, whiteSpace | Represents the ENTITY attribute type in XML 1.0 Recommendation. This is a reference to an unparsed entity with a name that matches the specified name. An ENTITY must be an NCName and must be declared in the schema as an unparsed entity name.
QName | length, enumeration, pattern, maxLength, minInclusive, minExclusive, maxInclusive, maxExclusive, minLength, whiteSpace | Represents a qualified name. A qualified name is composed of a prefix and a local name separated by a colon. Both the prefix and local names must be an NCName. The prefix must be associated with a namespace URI reference, using a namespace declaration.

See Also

XML Schema Element Map | XML Data Types Reference | Derived XML Data Types | Data Type Facets


Derived XML Data Types

[This is preliminary documentation and subject to change.]

The following table lists derived XML schema data types, facets that can be applied to the derived data type, and a description of the derived data type.

Data Type | Facets | Description
CDATA | enumeration, pattern, length, minLength, maxLength, whiteSpace | Represents white space normalized strings. This data type is derived from string.
Language | length, pattern, maxLength, minLength, enumeration, whiteSpace | Represents natural language identifiers (defined by RFC 1766).
IDREFS | length, maxLength, minLength, enumeration, whiteSpace | Represents the IDREFS attribute type. IDREFS contains a set of values of type IDREF.
ENTITIES | length, maxLength, minLength, enumeration, whiteSpace | Represents the ENTITIES attribute type. ENTITIES contains a set of values of type ENTITY.
NOTATION | length, enumeration, pattern, maxLength, minInclusive, minExclusive, maxInclusive, maxExclusive, minLength, whiteSpace | Represents the NOTATION attribute type in the XML 1.0 Recommendation. This is a reference to a notation with a name that matches the specified name. A NOTATION must be a no-colon-name (NCName) and must be declared in the schema as a notation name.
NMTOKEN | length, pattern, maxLength, minLength, enumeration, whiteSpace | Represents the NMTOKEN attribute type. An NMTOKEN is set of name characters (letters, digits, and other characters) in any combination. Unlike Name and NCName, NMTOKEN has no restrictions on the starting character.
NMTOKENS | length, maxLength, minLength, enumeration, whiteSpace | Represents the NMTOKENS attribute type. NMTOKENS contains a set of values of type NMTOKEN.
Name | length, pattern, maxLength, minLength, enumeration, whiteSpace | Represents names in XML. A Name is a token that begins with a letter, underscore, or colon and continues with name characters (letters, digits, and other characters).
NCName | length, pattern, maxLength, minLength, enumeration, whiteSpace | Represents "noncolonized" names. This data type is the same as Name, except it cannot begin with a colon.
integer | enumeration, pattern, scale, precision, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents a sequence of decimal digits with an optional leading sign (+ or -). This data type is derived from decimal.
nonPositiveInteger | enumeration, pattern, scale, precision, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents an integer that is less than or equal to zero. A nonPositiveInteger consists of a negative sign (-) and sequence of decimal digits. This data type is derived from integer.
negativeInteger | enumeration, pattern, scale, precision, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents an integer that is less than zero. A negativeInteger consists of a negative sign (-) and sequence of decimal digits. This data type is derived from nonPositiveInteger.
long | enumeration, pattern, scale, precision, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents an integer with a minimum value of -9223372036854775808 and maximum of 9223372036854775807. This data type is derived from integer.
int | enumeration, pattern, scale, precision, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents an integer with a minimum value of -2147483648 and maximum of 2147483647. This data type is derived from long.
short | enumeration, pattern, scale, precision, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents an integer with a minimum value of -32768 and maximum of 32767. This data type is derived from int.
token | enumeration, pattern, length, minLength, maxLength, whiteSpace | Represents tokenized strings. This data type is derived from CDATA.
byte | enumeration, pattern, scale, precision, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents an integer with a minimum value of -128 and maximum of 127. This data type is derived from short.
nonNegativeInteger | enumeration, pattern, scale, precision, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents an integer that is greater than or equal to zero. This data type is derived from integer.
unsignedLong | enumeration, pattern, scale, precision, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents an integer with a minimum of zero and maximum of 18446744073709551615. This data type is derived from nonNegativeInteger.
unsignedInt | enumeration, pattern, scale, precision, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents an integer with a minimum of zero and maximum of 4294967295. This data type is derived from unsignedLong.
unsignedShort | enumeration, pattern, scale, precision, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents an integer with a minimum of zero and maximum of 65535. This data type is derived from unsignedInt.
unsignedByte | enumeration, pattern, scale, precision, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents an integer with a minimum of zero and maximum of 255. This data type is derived from unsignedShort.
positiveInteger | enumeration, pattern, scale, precision, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents an integer that is greater than zero. This data type is derived from nonNegativeInteger.
timeInstant | period, duration, enumeration, pattern, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents an instant of time. This data type is derived from recurringDuration.
time | period, duration, enumeration, pattern, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents the time of day. This data type is derived from recurringDuration.
timePeriod | period, duration, enumeration, pattern, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents a period of time with a start and an end. This data type is derived from recurringDuration. This data type cannot be used directly in a schema. Only derived data types that specify duration can be used.
date | period, duration, enumeration, pattern, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents a time period that begins at midnight of the specified day and ends at midnight the following day. This data type is derived from timePeriod. The format of the date is CCYY-MM-DD. Example: 2000-09-27
month | period, duration, enumeration, pattern, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents a time period that begins at midnight of the first day of the specified month and ends at midnight of the last day. This data type is independent of the number days in the month. This data type is derived from timePeriod.
year | period, duration, enumeration, pattern, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents a time period that begins at midnight of the first day of the specified year and ends at midnight of the last day. This data type is independent of the number days in the year. This data type is derived from timePeriod.
century | period, duration, enumeration, pattern, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents a time period that begins at midnight of the first day of the specified century and ends at midnight of the last day. This data type is derived from timePeriod.
recurringDate | period, duration, enumeration, pattern, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents a recurring day in the year. This data type is derived from recurringDuration.
recurringDay | period, duration, enumeration, pattern, minInclusive, minExclusive, maxInclusive, maxExclusive, whiteSpace | Represents a recurring day in the month. This data type is derived from recurringDuration.

See Also

XML Schema Element Map | XML Data Types Reference | Primitive XML Data Types | Data Type Facets


Data Type Facets

[This is preliminary documentation and subject to change.]

Simple types (both built-in and derived) have facets. A facet is a single defining aspect that helps determine the set of values for a simple type. For example, length, minInclusive, and maxInclusive are common facets for the built-in data types. All of the facets for a simple type define the set of legal values for that simple type.

A facet is defined as an element. Each facet element has a fixed attribute that is a Boolean value. When a simple type is defined, you can prevent derivatives of that type from modifying the value of specified facets. To prevent modification of a facet, add the fixed attribute to the facet and set its value to true.

Example

The following example shows a simple type with the fixed attribute set to true which prevents the length from having any other value than 7.

<xsd:simpleType name="Postcode">
 <xsd:restriction base="string">
  <xsd:length value="7" fixed="true"/>
 </xsd:restriction>
</xsd:simpleType>

List of Constraining Facets

The following table lists the constraining facets (facets that can be used to constrain the values of simple types), their descriptions, and the built-in data types that they apply to.

Facet | Description
duration | Duration of values for recurringDuration and its derivatives. This value must be a timeDuration.
encoding | Encoded form of data types derived from binary. This value must be one of the following: hex base64
enumeration | Specified set of values. This constrains a data type to the specified values.
length | Number of units of length. Units of length depend on the data type. This value must be a nonNegativeInteger.
maxExclusive | Upper bound value (all values are less than this value). This value must be the same data type as the inherited data type.
maxInclusive | Maximum value. This value must be the same data type as the inherited data type.
maxLength | Maximum number of units of length. Units of length depend on the data type. This value must be a nonNegativeInteger.
minExclusive | Lower bound value (all values are greater than this value). This value must be the same data type as the inherited data type.
minInclusive | Minimum value. This value must be the same data type as the inherited data type.
minLength | Maximum number of units of length. Units of length depend on the data type. This value must be a nonNegativeInteger.
pattern | Specific pattern that the data type's values must match. This constrains the data type to literals that match the specified pattern. The pattern value must be a regular expression.
period | Frequency of recurrence for recurringDuration and its derivatives. This value must be a timeDuration.
precision | Maximum number of digits for data types derived from decimal. This value must a positiveInteger.
scale | Maximum number of digits in the fractional portion for data types derived from decimal. This value must a nonNegativeInteger.
whiteSpace | Value must be one of preserve, replace, or collapse.

See Also

XML Schema Element Map |XML Data Types Reference | Primitive XML Data Types | Derived XML Data Types


XDR Schema Developer's Guide

XML-Data Reduced (XDR) language is a subset of ideas described in the XML-Data specification, specifically the W3C's XML-Data Note posted in January 1998 and Document Content Description (DCD) initiative for XML.

MSXML2.0 and later provide XDR schema support.

For more information about authoring XDR schemas, see the following topics.

  • Referencing XDR Schemas in XML Documents
  • Defining Elements and Attributes
  • Content Model
  • XDR Data Types
  • Extensibility
  • XDR Schemas and the DOM
  • XDR Schemas and Namespaces
  • Using Inline Schemas
  • Representing the XDR Schema as a DTD

Other Resources Other Resources

XML-Data Note | Document Content Description (DCD) for XML


Referencing XDR Schemas in XML Documents

To reference an XDR schema from an XML document, include a schema namespace declaration, as in the following XML document.

Example

The following example shows an XML document that references an XDR schema, yourschema.xml.

<book xmlns="x-schema:yourschema.xml">
  <title>Presenting XML</title>
  <author>Richard Light</author>
</book>

In MSXML 2.0 and later versions, a schema can be included inline within the document that references it. The pound sign (#) before the schema name indicates that the schema is inline.

Example

The following example shows an XML document that references an inline XDR schema.

<root xmlns:data="x-schema:#inLineSchema">
   <Schema name ="inLineSchema"
           xmlns="urn:schemas-microsoft-com:xml-data">
   <ElementType name="myelement"/>
   </Schema>
   <data:myelement>inline example</data:myelement>
</root>

See Also

Using Inline Schemas


Defining Elements and Attributes

When defining schema for a particular class of documents, you specify which elements and attributes are allowed in a complying XML document, and how those elements and attributes are related to each other. In the XML-Data Reduced (XDR) schema, specifying an ElementType element and AttributeType element defines the elements and attributes, respectively. Then an instance of an element or an attribute is declared using Element element or attribute element tags.

Example

The following example shows an XDR schema that defines four elements: <title>, <author>, <pages>, and <book> using ElementType element. The definition of the <book> element includes the content model for that element, which specifies that each <book> element contains <title>, <author>, and <pages> child elements. This content model is specified using element element along with the type attribute that references the element type defined earlier.

The schema also declares an attribute, "copyright", for the <book> element by using the AttributeType element, which defines an attribute type, and then declares it using the attribute element.

<?xml version="1.0"?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data">
  <ElementType name="title"/>
  <ElementType name="author"/>
  <ElementType name="pages"/>
  <ElementType name="book" model="closed">
    <element type="title"/>
    <element type="author"/>
    <element type="pages"/>

    <AttributeType name="copyright"/>
    <attribute type="copyright"/>
  </ElementType>
</Schema>

Data file

<r xmlns:a="x-schema:abovefile.xml">
<a:book a:copyright="">
  <a:title/>
  <a:author/>
  <a:pages/>
</a:book>
</r>

Specifying global AttributeType elements

You can specify the AttributeType element globally by placing it outside the context of any ElementType element. This allows multiple elements to share the definition of a common attribute.

Example

The following example shows an XDR schema with multiple elements that share the definition of the "copyright" attribute.

<?xml version="1.0"?>
<Schema xmlns="schemas-microsoft-com:xml-data">
  <ElementType name="title"/>
  <ElementType name="author"/>
  <ElementType name="pages"/>
  <AttributeType name="copyright"/>
  <ElementType name="book" model="closed">
    <element type="title"/>
    <element type="author"/>
    <element type="pages"/>
    <attribute type="copyright"/>
  </ElementType>
</Schema>

Data file

<r xmlns:a="x-schema:abovefile.xml">
<a:book a:copyright="">
  <a:title/>
  <a:author/>
  <a:pages/>
</a:book>
</r>


Content Model

The content model describes the content structure of elements and attributes in the XML document. To describe the content structure, you can use the model, minOccurs, maxOccurs, order, content, minLength, maxLength, default, and type attributes.

In this section, the content model of an element is described first and then the content model of an attribute. Attributes used to describe the content model are introduced.

Specifying an Element's Content Model

When specifying the content model of an element:

  • Describe the child elements and attributes that can appear in the element.
  • Specify whether the element can include text and elements.
  • Specify the order in which the child elements can appear in an instance of the element.

Example

The following example describes the content model and elements for an XDR schema, BookSchema.xml.

<s:Schema xmlns:s="urn:schemas-microsoft-com:xml-data">
  <s:ElementType name="title" content="textOnly"/>
  <s:ElementType name="authors" content="textOnly"/>
  <s:AttributeType name="pages" content="textOnly"/>
  <s:ElementType name="book" order="seq" content="eltOnly">
    <s:attribute type="pages"/>
    <s:element type="title"/>
    <s:element type="authors"/>
  </s:ElementType>
</s:Schema>

The content model for the <title>, <author>, and <pages> elements is straightforward. Because the content attribute specifies the elements as "textOnly", these elements contain text and nothing else (that is, no child elements).

The content model for the <book> element is more complex. The content attribute for the <book> element is "eltOnly". This value means that the <book> element can contain only the elements specified (<title>, <author>, and <pages>) in the schema. Furthermore, for each <book> element instance in the document, the child elements must be in the order specified in the schema, validated by setting the order attribute to the value of "seq".

This is a valid instance of the XML document.

<x:book xmlns:x="x-schema:BookSchema.xml">
  <x:pages>474</x:pages>
  <x:title>Applied XML: A Toolkit for Programmers</x:title>
  <x:authors>Alex Ceponkus and Faraz Hoodbhoy</x:authors>
<x:/book>

The following paragraphs describe the attributes used by the content model.

The model Attribute (Open and Closed Content Models)

The content model attribute of an element can have the values "open" or "closed". In an open content model, an element in an XML document can have additional child elements and attributes that are not declared in the XDR schema that the document references. Conversely, a closed model is one in which the document cannot include any information that does not follow the rules specified in the referenced schema.

By default, the content model for an XDR schema is open. This provides an XDR schema with the extensibility that is not present in a document type definition (DTD), which is a closed model. When using a DTD, a document cannot include any information that does not follow the rules specified in the referenced DTD.

For example, consider this document fragment.

<x:book xmlns:x="x-schema:BookSchema.xml"
        xmlns:y="urn:some-new-namespace">
  <x:title y:id="123">Applied XML: A Toolkit for Programmers</x:title>
  <x:authors>Alex Ceponkus and Faraz Hoodbhoy</x:authors>
  <x:pages>474</x:pages>
  <y:publisher>Wiley Computer Publishing</y:publisher>
</x:book>

This fragment refers to the BookSchema.xml schema presented earlier. Because this schema specifies an open content model (the default), this document fragment is valid even though it has additional elements and attributes not specified in BookSchema.xml (such as the id attribute in the <title> element and the <publisher> child element, both of which are defined in urn:some-new-namespace namespace).

In an open content model, the following constraints apply.

  • Content that breaks the existing content model cannot be added or removed. For example, BookSchema.xml defines the <book> element as a sequence of three elements. Therefore, you must first provide that exact sequence of elements before adding any open content. Thus, you cannot remove the <pages> element, nor can you provide two <title> elements next to each other. Doing so will cause validation to fail.
  • Undeclared elements can be added as long as they are defined in a different namespace.
  • After satisfying the content model for the schema, other elements can be added. For example, an XML document will validate even if a second <title> element is added after the <pages> element.

Specify a closed content model if you do not want the default value of "open" to be used. In this case, you use the model attribute for the ElementType, as in the following example.

<x:ElementType name="book" model="closed">

This indicates that a <book> element can only contain the content specified—the <title>, <author>, and <pages> elements—in the schema. Using this setting, the extended elements in the preceding XML fragment would prevent the document from being validated.

The content Attribute

When describing the content model, you use the content attribute to specify whether an element can contain only text (content="textOnly"), only elements (content="eltOnly"), a mixture of text and elements (content="mixed"), or nothing at all (content="empty"). The default value for this attribute is "mixed".

If the <ElementType> has a data type specified (such as date, number, and so on), then the element is assumed to contain only text ("textOnly" value is implied for content attribute).

For example, the following XDR schema defines a <book> element that contains three child elements: <title>, <author>, and <pages>. These child elements can contain only text because the content attribute for each of these elements is "textOnly". The <book> element can contain only elements and no text because its content attribute is "eltOnly". This <book> element uses a closed content model (model="closed"). Thus, the <book> element can contain only these three child elements and no text or additional subelements and attributes.

<?xml version="1.0"?>
<Schema xmlns:s="schemas-microsoft-com:xml-data">
  <s:ElementType name="title" content="textOnly" />
  <s:ElementType name="author" content="textOnly" />
  <s:AttributeType name="pages" content="textOnly" />
  <s:ElementType name="book"  content="eltOnly" model="closed">
    <s:element type="title" />
    <s:element type="author" />
    <s:attribute type="pages" />

    <s:AttributeType name="copyright" />
    <s:attribute type="copyright" />
  </s:ElementType>
</Schema>

If the content attribute for an element is "empty", that element cannot contain any text or child elements; however, it can have attributes. A "mixed" element, on the other hand, can contain text and child elements.

The minOccurs and maxOccurs Attributes

You can specify how many times a child element can appear within its parent element by using the minOccurs and maxOccurs attributes.

<element type="Item" maxOccurs="*" />

The maxOccurs attribute is a constraint rule, specifying the maximum number of times that a child element may appear. Valid values for maxOccurs are 1 and "*"; the "*" indicates that an unrestricted number of elements can appear. The default value for maxOccurs is "1"; however, when content="mixed", the default value is "*".

In a similar way, you can specify a minimum number of times a child element can appear with minOccurs. The valid values for minOccurs are "0" and "1". For example, to make a child element optional in the instance of parent element, set minOccurs to "0". The default value for minOccurs is "1".

In the following schema, the <author> element sets maxOccurs to "*" while the <pages> element sets the minOccurs attribute to "0".

<?xml version="1.0"?>
<Schema xmlns:s="schemas-microsoft-com:xml-data">
  <s:ElementType name="title" content="textOnly" />
  <s:ElementType name="author" content="textOnly" />
  <s:ElementType name="pages" content="textOnly" />
  <s:ElementType name="book"  content="eltOnly" model="closed">
    <s:element type="title" />
    <s:element type="author" maxOccurs="*" />
    <s:element type="pages" minOccurs="0" />
  </s:ElementType>
  <s:ElementType name="root" >
    <s:element type="book" />
  </s:ElementType>
</Schema>

Based on this example schema, the following is a valid document instance.

<root>
  <book>
    <title>C Programming</title>
    <author>Author A</author>
    <author>Author B</author>
    <pages>300</pages>
  </book>
  <book>
    <title>Java Programming</title>
    <author>Author C</author>
  </book>
</root>

The minLength and maxLength Attributes

You can specify a data type for an element or attribute by using the "urn:schemas-microsoft-com:datatypes" namespace. The minLength and maxLength attributes defined in this namespace can be used to constrain the length of a string, number, bin.hex, or bin.base64 data type.

  • For string and number data types, maxLength specifies the maximum number of characters allowed, while minLength specifies the minimum number of characters.
  • For bin.hex and bin.base64, maxLength sets the maximum number of bytes of the binary object, while minLength sets the minimum number of bytes.

Regardless of the data type, both length attributes are inclusive. That is, the data can be as long as the length set by maxLength, but no longer, and as short as the length set by minLength, but no shorter.

The maxLength and minLength attributes are enforced at parse time and run-time. Valid parent elements are <ElementType/>, <AttributeType/>, and <dataType/>.

The following XDR schema shows an example of how to use these length attributes. This schema specifies the content model for the <userID>, <password>, and <LoginInfo> elements. However, only the content model of the <password> element specifies a minimum and maximum length (6 to 8 characters) for the required string.

<?xml version="1.0"?>
<Schema xmlns:s="schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes" >
  <s:AttributeType name="userID"
             xmlns:dt="urn:schemas-microsoft-com:datatypes"
             dt:type="string" />
  <s:AttributeType name="password"
             dt:type="string"
             dt:minLength="6"
             dt:maxLength="8"/>
  <s:ElementType name="LoginInfo" >
    <s:attribute type="userID" />
    <s:attribute type="password" />
  </s:ElementType>
</Schema>

Using the preceding schema, these two documents are valid instances.

<LoginInfo userID="1" password="xyz" />
<LoginInfo userID="2" password="" />

Although the password attribute value in the second instance is less than the minLength, the instance is still valid because a password value specified as "" is treated the same as if the password attribute is not specified.

The order Attribute

When specifying the content model, you use the order attribute to specify how sequences of elements can appear in the document instance. You can assign the order attribute the value of "seq", "one", or "many".

The "seq" value indicates that the enclosed elements must appear in the same order as they appear in the schema, as in the following example.

<ElementType name="PurchaseOrder" order="seq">
  <element type="PONumber" />
  <element type="PODate" />
  <element type="ShipAddress" />
</ElementType>

The "one" value specifies that only one of the child elements defined in an <ElementType> can appear. For example, to specify that an <Item> element can contain either a <product> element or a <backOrderedProduct> element, but not both, the schema can be specified as follows.

<ElementType name="Item" order="one">
   <element type="product" />
   <element type="backOrderedProduct" />
</ElementType>

The "many" value specifies that the child elements can appear in any order, and in any quantity.

The default value for the order attribute depends on the content model in use. When the content attribute is not set or set to the value of "mixed", the default value for order is "many". When the content attribute is set to "eltOnly", the default value for order is "seq". Unexpected problems can occur when the order attribute is not set and the default value is inserted. For example, in this schema the order attribute is not specified.

<ElementType name="PONumber" />
<ElementType name="PODate" />
<ElementType name="ShipAddress" />
<ElementType name="product" />
<ElementType name="backOrderedProduct" />

<ElementType name="PurchaseOrder">
  <element type="PONumber" maxOccurs="1" />
  <element type="PODate" minOccurs="1" />
  <element type="ShipAddress" minOccurs="2" maxOccurs="unbounded" />

  <ElementType name="Item" content="eltOnly">
    <element type="product" />
    <element type="backOrderedProduct" />
  </ElementType>
</ElementType>

The schema appears to the parser as follows.

<ElementType name="PONumber" />
<ElementType name="PODate" />
<ElementType name="ShipAddress" />
<ElementType name="product" />
<ElementType name="backOrderedProduct" />

<ElementType name="PurchaseOrder" content="mixed" order="many">
  <element type="PONumber" maxOccurs="1" />
  <element type="PODate" minOccurs="1" />
  <element type="ShipAddress" minOccurs="2" maxOccurs="unbounded" />

  <ElementType name="Item" content="eltOnly" order="seq">
    <element type="product" />
    <element type="backOrderedProduct" />
  </ElementType>
</ElementType>

Using the preceding schema will not produce the expected validation of the document. Now multiple instances of the element can be entered without an error occurring, as shown in this XML document example.

<?xml Version="1.0"?>
<PurchaseOrder xmlns="http://www.someserver.com" schemaLocation="http://www.someserver.com/someschema.xml">
<!-- The following lines would validate against the schema -->
  <PONumber>1234</PONumber>
  <PONumber>1235</PONumber>
  <ShipAddress>555 Nowhere Blvd</ShipAddress>
<!-- The following lines would not validate against the schema -->
   <Item>
      <backOrderedProduct>firstBOproduct</backOrderedProduct>
      <Product>firstprod</Product>
   </Item>
</PurchaseOrder>

The order attribute is valid for either an <ElementType> or <group> element.

The <group> Element

The <group> element enables you to specify constraints on a subset of child elements. This can be quite useful when specifying elements within a schema.

The <group> element accepts the order, minOccurs, and maxOccurs attributes.

For example, the following schema defines the <Item> element as containing a <group> element with two child elements, <product> and <backOrderedProduct>. Because this <group> element sets its order attribute to "one", only one of these child elements can appear in the <Item> element. This prevents the <Item> element from having both a <product> and a <backOrderedProduct> element. The <Item> element can have only one of these child elements.

<ElementType name="Item">
    <group order="one">
        <element type="product" />
        <element type="backOrderedProduct" />
    </group>
    <element type="quantity"/>
    <element type="price"/>
</ElementType>

Using the preceding schema, the following document is a valid instance.

<Item>
  <product>CD</product>
  <quantity>100</quantity>
  <price>10</price>
</Item>
<Item>
  <product>FloppyDisk</product>
  <quantity>100</quantity>
  <price>1</price>
</Item>

Specifying an Attribute's Content Model

The <AttributeType> element specifies the type of attribute used within elements. Using this element, you can even specify whether the attribute is required for the element, as in the following.

<AttributeType name="shipTo" dt:type="idref" required="yes"/>

The <attribute> element specifies instances of an attribute defined within the <AttributeType> element. You use the <attribute> element within an <ElementType> element.

Attributes are more limited in some ways than elements. For example, attributes cannot contain child elements, and you cannot require attributes to appear in any particular order; nor can you pose alternatives, such as a "product" or a "backOrderedProduct". You can specify whether an attribute is required or optional, but an attribute can appear only once per element.

At the same time, attributes have the following capabilities that elements do not.

  • Attributes can limit their legal values to a small set of strings, as in this example.
    <AttributeType name="priority" dt:type="enumeration" dt:values="high medium low" />
  • Attributes indicate a value to be inferred if the attribute is omitted from an element (that is, the attribute's default value), as in the following example.
    <AttributeType name="quantity" dt:type="int">
<attribute type="quantity" default="1"/>

Although different element types can have attributes with the same name, these attributes are independent and unrelated.

Specifying an Attribute's Default Value

To specify an attribute's default value, use the default attribute. You specify this attribute on <AttributeType> and <attribute> elements in the schema.

For example, the following schema assigns the default value of "Seattle" to the City attribute.

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data" >
<ElementType name="Customer" >
    <AttributeType name="CustomerID" />
    <AttributeType name="ContactName" />
    <AttributeType name="City" default="Seattle" />

    <attribute type="CustomerID" />
    <attribute type="ContactName" />
    <attribute type="City"  />
</ElementType>
</Schema>

If you have a document instance that has a <Customer> element with a missing City attribute, the parser assumes the default value ("Seattle") for the attribute and validates the document. For example, consider this document instance.

<Customer CustomerID="ALFKI" ContactName="Maria Anders" City="London" />
<Customer CustomerID="ANATR" ContactName="Ana Trujillo" />

The customer "ALFKI" specifies a city ("London"), so the default value is ignored. On the other hand, the customer "ANATR" has no City attribute, so it receives the default value ("Seattle").

The behavior is slightly different if the schema specifies both a default attribute and a required attribute. For example, the following <AttributeType> specifies the City attribute as required with a default value of "Seattle".

<AttributeType name="City" default="Seattle" required="yes" />

The <Customer> element is required to have a City attribute and it must have "Seattle" as its value.


Using XDR Data Types

In an XML-Data Reduced (XDR) schema, you can specify the data types of elements and attributes. In addition to supporting the attribute types found in a document type definition (DTD), the XDR schema provides support for a range of data types.

The data types indicate the format of the data and enable processing specific to that data type in the XML Document Object Model (DOM). Also, the XML parser uses the data type information for validation of the type.

To specify data types in the XDR schema, the schema must include the data type namespace, urn:schemas-microsoft-com:datatypes.

This is the minimum XDR schema with the namespace declarations.

<?xml version="1.0" ?>
<Schema name="MySchema" xmlns="urn:schemas-microsoft-com:xml-data"
                        xmlns:dt="urn:schemas-microsoft-com:datatypes" >
    …
</Schema>

Using the following link will display a list of the data types supported in XDR schemas.

XDR Data Types


Specifying Data Types

Although XML-Data Reduced (XDR) schema support in MSXML 2.0 allows data types to be specified within attributes, only the following data types are supported within attributes by the Microsoft XML Parser (MSXML) and the Document Object Model (DOM).

  • string
  • id
  • idref
  • idrefs
  • nmtoken
  • nmtokens
  • enumeration

In MSXML 2.0, the list of data types that can apply to elements did not include the attribute types. These restrictions were lifted in MSXML 2.5 (released with Microsoft Windows® 2000 and Internet Explorer 5.01) although attribute type data types other than id, idref, and idrefs on elements were not validated. With MSXML 2.6 and later, attributes and elements have equivalent functionality.

Example A—Specifying the Data Type in the Schema

The following schema examples specify data types, such as string, nmtoken, int, float, boolean, and so on, when declaring an element or attribute.

In this example, the dt:type attribute declares the data type of the att1 attribute.

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes" >
  <AttributeType name="att1" dt:type="int"/>
  <ElementType name="Element1">
    <element type="Element1"/>
    <attribute type="att1"/>
  </ElementType>
</Schema>

<?xml version="1.0" ?>
<r xmlns:a="x-schema:abovefile.xml">
  <a:Element1 a:att1=22>
  </a:Element1>
</r>
Alternatively, you can specify the data type using the <datatype> element as in this example.
<AttributeType name="att1">
    <datatype dt:type="int"/>
</AttributeType>

Example B—Specifying id/idref/idrefs Types in the Schema

This example illustrates how the id, idref, and idrefs attribute data types of a document type definition (DTD) are specified in XDR schema. The schema describes the <Employee> and <Order> elements.

Because an employee takes orders, the OrderList attribute of <Employee> element is declared as idrefs type, referring to OrderID attribute of <Order> element. Conversely, because an order is taken by an employee, the EmployeeID attribute of <Order> element is declared as idref type, referring to EmployeeID attribute of <Employee> element.

<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes" >
  <ElementType name="Order" >
    <AttributeType name="OrderID" dt:type="id"/>
    <AttributeType name="OrderDate"/>
    <AttributeType name="EmployeeID" dt:type="idref"/>

    <attribute type="OrderID"/>
    <attribute type="OrderDate"/>
    <attribute type="EmployeeID"/>
  </ElementType>
  <ElementType name="Employee">
    <AttributeType name="EmployeeID" dt:type="id"/>
    <AttributeType name="LastName"/>

    <attribute type="EmployeeID"/>
    <attribute type="LastName"/>
    <AttributeType name="OrderList" dt:type="idrefs"/>
    <attribute type="OrderList"/>
  </ElementType>
</Schema>

A roughly equivalent DTD would look as follows.

  <!ELEMENT Order EMPTY >
  <!ATTLIST Order
            OrderID    ID    #IMPLIED
            OrderDate  CDATA #IMPLIED
            EmployeeID IDREF #IMPLIED >

  <!ELEMENT Employee EMPTY>
  <!ATTLIST Employee
            Employee  ID ID  #IMPLIED
            LastName  CDATA  #IMPLIED
            OrderList IDREFS #IMPLIED >

An instance of the XML fragment is shown in the following. It shows a list of order IDs as value of OrderList attribute in the <Employee> element. If any of these values do not exist as the value of OrderID attribute of <Order> element, an error will be raised.

In a similar way, EmployeeID attribute of <Order> element is an idref attribute, referring to EmployeeID attribute of <Employee> element, thus forming an intra-document link. The id and idref relationships are similar to the primary key and foreign key relationships in relational databases.

  <Order OrderID="O1" OrderDate="1996-07-17T00:00:00" EmployeeID="Emp1" />
  <Order OrderID="O2" OrderDate="1996-08-01T00:00:00" EmployeeID="Emp1" />
  <Order OrderID="O3" OrderDate="1996-08-07T00:00:00" EmployeeID="Emp1" />
  <Order OrderID="O4" OrderDate="1996-08-20T00:00:00" EmployeeID="Emp2" />
  <Order OrderID="O5" OrderDate="1996-08-20T00:00:00" EmployeeID="Emp2" />
  ...
  <Employee EmployeeID="Emp1"
            LastName="Davolio"
            OrderList="O1 O2 O3">
  </Employee>
  <Employee EmployeeID="Emp2"
            LastName="Fuller"
            OrderList="O4 O5">
  </Employee>
  ...
  ...

Example C—Specifying the Data Type in an XML Document Instance

You can specify the data type of an element without requiring the use of a schema. To do this, you can use the dt:dt attribute or declare the data type as an element.

The following document instance shows how to specify the data type using the dt:dt attribute. In this example, the dt:dt attribute specifies the int data type for the <Pages> element.

<BookInfo xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <Title>XML for Fertilizer</Title>
  <Pages dt:dt="int" >123</Pages>
</BookInfo>

Now, consider the following document instance. It uses the dt:dt attribute as in the preceding example. In this case, the attribute specifies the data type of the <size> element.

<shoes xmlns:dt="urn:schemas-microsoft-com:datatypes" id="f1121" sizes="mens" >
  <sizes id="mens" >
    <size dt:dt="int" >8</size>
    <size dt:dt="int" >10</size>
    <size dt:dt="int" >12</size>
  </sizes>
<shoes>

However, you can rewrite the preceding instance so that you declare the data types as elements, as shown in the following.

<shoes xmlns:dt="urn:schemas-microsoft-com:datatypes" id="f1121" sizes="mens" >
  <sizes id="mens" >
    <dt:int>8</dt:int>
    <dt:int>10</dt:int>
    <dt:int>12</dt:int>
  </sizes>
<shoes>

The following are some guidelines for working with data type elements.

  • The dataType property on data type elements is read-only and returns the data type of the element. To return the typed value of the element, use the nodeTypedValue property instead. Using the nodeTypedValue property on an element that has no data type returns the string value of the element.
  • The parser validates the contents of data type elements against the type of the element. If the parser does not support a data type, it disregards that data type and no error occurs.
  • A data type element cannot have child elements.

Example D—Using Enumerations

In this example, the schema specifies "enumeration" as the data type for an attribute.

<AttributeType name = "Attr1"
             dt:type="enumeration" dt:values="a b c"/>

In MSXML 2.6 and later, elements also support the enumeration data type.

<ElementType name = "Ele1"
             dt:type="enumeration" dt:values="a b c"/>

The following element is a valid instance for the preceding type declaration.

<Ele1>b</Ele1>

You can also specify the enumeration data type on an instance of the element. For example, the following element, <Ele1>, contains a type declaration and declares its values.

<Ele1 dt:dt="enumeration" dt:values="a b c"
      xmlns:dt="urn:schemas-microsoft-com:datatypes">b</Ele1>

See Also

dataType Property | nodeTypedValue Property


Extensibility

Unlike a document type definition (DTD), XML-Data Reduced (XDR) schemas are extensible. That is, they are built on an open content model. Schema authors are free to add their own elements and attributes to XDR schema documents. For example, you can add additional constraints to a declaration for a "pages" element. The following sample code declares the "pages" element and assigns it an "int" data type. Extended tags from the "myExt" namespace are used to augment this information with an added limitation that books must have a minimum of 50 pages and a maximum of 100 pages.

<ElementType name="pages" xmlns:myExt="urn:myschema-extensions">
  <datatype dt:type="int" />
  <myExt:min>50</myExt:min>
  <myExt:max>100</myExt:max>
</ElementType>

Although validation will only check that the value of a particular "pages" element is an integer, your application can use the information provided by the added elements in the "myExt" namespace to perform additional validation.

The elements that Microsoft added to the schema were qualified by a namespace. Use of a namespace is a requirement for adding elements and attributes to a schema. For more information about namespaces, see Using Namespaces in Documents.

Referencing Other Schemas

Custom schemas can be built out of standard parts. For example, suppose that a definition for an "Address" element from another schema has met your needs. With namespaces, this schema can be used directly with a reference to the original schema rather than copying the definition.

To reference an element defined in another schema, you must first use a namespace declaration to introduce the other schema. This declaration consists of an attribute beginning with "xmlns:", followed by a name of your choice, called the prefix, and a value that is the Uniform Resource Identifier (URI) of the other schema.

<ElementType name="PurchaseOrder"
             xmlns:abcde="http://electrocommerce.org/stuff.xml">

The schema has a namespace URI of "http://electrocommerce.org/stuff.xml" and a prefix of "abcde". The namespace URI identifies the other schema precisely; the prefix is a local name that you now use to refer to that schema and to the elements it defines as though they were defined in your schema. If the other schema has a suitable "shipTo" element defined, you can use it by writing the following.

<ElementType name="shipTo"
             xmlns:abcde="http://electrocommerce.org/stuff.xml">
   <element type="abcde:Address"/>
</ElementType>

In the type attribute of the first child element declaration for the value "abcde:Address", the prefix "abcde" is matched to the enclosing namespace declaration; thus, "abcde:Address" has the effect of meaning "the Address element" as defined in the schema "http://electrocommerce.org/stuff.xml".

However, this has an effect on the XML document as well. For example, in the following purchase order document you must also reference the other schema namespace.

<PurchaseOrder xmlns:abcde="http://electrocommerce.org/stuff.xml">
  <shipTo>
    <abcde:Address>
      <abcde:name>Alice Smith</abcde:name>
      <abcde:street>123 Maple Street</abcde:street>
      <abcde:city>Mill Valley</abcde:city>
      <abcde:state>CA</abcde:state>
      <abcde:zip>90952</abcde:zip>
    </abcde:Address>
  </shipTo>
  <orderDate>1999-05-20</orderDate>
  <shipDate>1999-05-25</shipDate>
  <comments>
    Get these things to me in a hurry, my lawn is going wild!
  </comments>
  <Items>
    <Item>
      <productName>Lawnmower, model BUZZ-1</productName>
      <quantity>1</quantity>
      <price>148.95</price>
    </Item>
    <Item>
      <productName>Weed Wacker, model SNOOZE-2</productName>
      <quantity>1</quantity>
      <price>39.98</price>
    </Item>
  </Items>
</PurchaseOrder>

You can determine that the "Address" element is defined by the schema at "http://electrocommerce.org/stuff.xml". When you build specialized schemas from more widely understood standard parts, like the preceding "Address" element, those portions can often be processed by standard software components. For example, if you have an Extensible Stylesheet Language (XSL) template available for the "Address" element, as defined in the schema "http://electrocommerce.org/stuff.xml", you can reuse this general purpose address styling code anywhere that "Address" appears.

The same prefix is used in both the schema and in the document instance: in the schema for all purchase orders, and in a specific purchase order. However this is not necessary, because the prefix is only a local alias for the namespace URI, and you can use any prefix in the document instance. You are only required to use the same prefix in a document when you declare the namespace and when you use elements from that namespace, as in the following example.

<PurchaseOrder xmlns:z="http://electrocommerce.org/stuff.xml">
  <shipTo>
    <z:Address>
      <z:name>Alice Smith</z:name>
      <z:street>123 Maple Street</z:street>
      <z:city>Mill Valley</z:city>
      <z:state>CA</z:state>
      <z:zip>90952</z:zip>
    </z:Address>
  </shipTo>
</PurchaseOrder>

The declaration of a namespace is scoped to the element on which it appears. It makes the namespace prefix available, and associates it with the namespace URI for that element and anything it contains, unless overridden by another, enclosed namespace declaration. Therefore, because the namespace is only used on the "Address" element, the namespace declaration can appear on the "Address" element instead, as follows.

<PurchaseOrder>
  <shipTo>
    <z:Address xmlns:z="http://electrocommerce.org/stuff.xml">
      <z:name>Alice Smith</z:name>
      <z:street>123 Maple Street</z:street>
      <z:city>Mill Valley</z:city>
      <z:state>CA</z:state>
      <z:zip>90952</z:zip>
    </z:Address>
  </shipTo>
</PurchaseOrder>

Omitting Prefixes

You can also omit a prefix to a namespace, which can make for more legible documents. In the following example, by omitting the prefix from the namespace declaration, you indicate that any child element without a prefix is defined by the specified namespace.

<PurchaseOrder>
  <shipTo>
    <Address xmlns="http://electrocommerce.org/stuff.xml">
      <name>Alice Smith</name>
      <street>123 Maple Street</street>
      <city>Mill Valley</city>
      <state>CA</state>
      <zip>90952</zip>
    </Address>
  </shipTo>
</PurchaseOrder>

Namespace prefixes are only for intra-document bookkeeping. What matters is the corresponding namespace URI, so all four of the "Address" elements in the preceding examples mean exactly the same thing.

Although the "Address" element has been identified as being defined by the schema "http://electrocommerce.org/stuff.xml", "PurchaseOrder" has not been similarly tied to a schema. To do this, assuming a schema named "http://fabrikam.com/PO.xml" defines a "PurchaseOrder", you can write the following.

<PurchaseOrder xmlns="http://fabrikam.com/PO.xml">
  <shipTo>
    <Address xmlns="http://electrocommerce.org/stuff.xml"  >
      <name>Alice Smith</name>
      <street>123 Maple Street</street>
      <city>Mill Valley</city>
      <state>CA</state>
      <zip>90952</zip>
    </Address>
  </shipTo>
  <orderDate>1999-05-20</orderDate>
  <shipDate>1999-05-25</shipDate>
  <comments>
     Get these things to me in a hurry, my lawn is going wild!
  </comments>
  <Items>
    <Item>
      <productName>Lawnmower, model BUZZ-1</productName>
      <quantity>1</quantity>
      <price>148.95</price>
    </Item>
    <Item>
      <productName>Baby Monitor, model SNOOZE-2</productName>
      <quantity>1</quantity>
      <price>39.98</price>
    </Item>
  </Items>
</PurchaseOrder>

This declares that the "PurchaseOrder" element and all elements it contains are defined within the schema "http://fabrikam.com/PO.xml", except for "Address" and the elements it contains, which are defined within xmlns="http://electrocommerce.org/stuff.xml". In both cases, explicit prefixes are omitted.

Multiple Namespaces

You can declare multiple namespaces on a single element. You can also use several prefixes to refer to the same namespace. The following example demonstrates this can be done and shows that this document is functionally equivalent to the previous one.

<PurchaseOrder xmlns:a="http://fabrikam.com/PO.xml"
xmlns:b="http://electrocommerce.org/stuff.xml"
xmlns:c="http://electrocommerce.org/stuff.xml">
  <a:shipTo>
    <b:Address >
      <c:name>Alice Smith</c:name>
      <b:street>123 Maple Street</b:street>
      <c:city>Mill Valley</c:city>
      <b:state>CA</b:state>
      <c:zip>90952</c:zip>
    </b:Address>
  </a:shipTo>
  <a:orderDate>1999-05-20</a:orderDate>
  <a:shipDate>1999-05-25</a:shipDate>
  <a:comments>
      Get these things to me in a hurry, my lawn is going wild!
  </a:comments>
  <a:Items>
    <a:Item>
      <a:productName>Lawnmower, model BUZZ-1</a:productName>
      <a:quantity>1</a:quantity>
      <a:price>148.95</a:price>
    </a:Item>
    <a:Item>
      <a:productName>Baby Monitor</a:productName>
      <a:quantity>1</a:quantity>
      <a:price>39.98</a:price>
    </a:Item>
  </a:Items>
</a:PurchaseOrder>

Open Content Model

If a document schema has elements with an open content model, you can include elements not mentioned in the original schema, provided they are assigned to a specific namespace, either with a default namespace in scope or with a prefix. You can also include undefined attributes in an element, provided the attribute is qualified by a prefix and the prefix is in scope. For example, suppose that a third schema defines an element called "trackingInformation". Because "PurchaseOrder" is defined as having an open content model, you can simply add this element directly to the instance.

<PurchaseOrder xmlns="http://fabrikam.com/PO.xml">
  <shipTo>
    <Address xmlns="http://electrocommerce.org/stuff.xml">
      <name>Denise Smith</name>
      <street>123 Maple Street</street>
      <city>Mill Valley</city>
      <state>CA</state>
      <zip>90952</zip>
    </Address>
  </shipTo>
  <orderDate>1999-05-20</orderDate>
  <shipDate>1999-05-25</shipDate>
  <comments>
      Get these things to me in a hurry. My lawn is going wild!
  </comments>
  <Items>
    <Item>
      <productName>Lawnmower, model BUZZ-1</productName>
      <quantity>1</quantity>
      <price>148.95</price>
    </Item>
    <Item>
      <productName>Baby Monitor, model SNOOZE-2</productName>
      <quantity>1</quantity>
      <price>39.98</price>
    </Item>
  </Items>
  <trackingInformation xmlns="http://somewhere.com/tracking.xml">
    <route>1234-5678</route>
    <signature>32143912850-3959159=1395</signature>
  </trackingInformation>
</PurchaseOrder>

Because namespace qualification is required for any undefined attribute or element, the "trackingInformation" element would not have been valid if its "xmlns" attribute had been omitted.


XDR Schemas and the DOM

When you use XML-Data Reduced (XDR) schema on an instant document, the schema definition of the elements and attributes in the instant document can be accessed using the definition property of the Document Object Model (DOM). The definition property of the IXMLDOMNode returns the type declaration that corresponds to the node just as it does in an external schema. The definition property does not work with inline schemas. The definition property returns the element in the schema that declared the type for the current element or attribute. For an element, defintion will return an <ElementType> element; for an attribute, it will return an <AttributeType> element. Although the schema's DOM is read-only and cannot be modified, it can be traversed, using all the functionality normally exposed through the DOM.

Consider the following example schema (Bookschema.xml) and XML documents.

Bookschema.xml

<?xml version="1.0"?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data">
  <ElementType name="title"/>
  <ElementType name="author"/>
  <ElementType name="pages"/>
  <AttributeType name="price"/>
  <ElementType name="book" model="closed">
    <element type="title"/>
    <element type="author"/>
    <element type="pages"/>
    <attribute type="price"/>
  </ElementType>
</Schema>

Book.xml

<?xml version ="1.0"?>
<a:book a:price="$12" xmlns:a="x-schema:bookschema.xml" >
  <a:title>Presenting XML</a:title>
  <a:author>Richard Light</a:author>
  <a:pages>334</a:pages>
</a:book>

Return the root element, the <a:book> node.

var bookNode = doc.documentElement;

Use the definition property on bookNode to get the ElementType definition for the <a:book> element.

var bookDef = bookNode.definition;

The following code returns the following element.

<ElementType xmlns="urn:schemas-microsoft.com:xml-data" name="book" model="closed">
   <element type="title"/>
   <element type="author"/>
   <element type="pages"/>
</ElementType>

Using bookDef, you can then access other schema information.

The following code selects element (0) in the childNodes element.

var title = bookDef.childNodes(0);
The following code returns the definition for the title element.
<element xmlns="urn:schemas-microsoft.com:xmldata" type ="title">

The following code selects element (1) in the childNodes element.

var author = bookDef.childNodes(1).xml;

The following code returns the definition for the author element.

<element xmlns="urn:schemas-microsoft.com:xmldata" type ="author">

The validate method of the DOMDocument attempts to validate the XML document to the schema(s) specified in the document.

The validateOnParse property of the DOMDocument controls the use of schemas for validation. Setting validateOnParse to False does not stop schemas from being loaded and processed. Doing this does prevent document validation, but the default attributes, ids and idrefs, and data types are all processed according to the schema.

Multiple schemas can appear in the same instance document as long as they conform to the ordering rules and their IDs do not conflict.

The resolveExternals property of the DOMDocument controls whether the parser resolves the document to an external schema. Setting resolveExternals to False will stop the parsing of "x-schema:" namespaces.

The SchemaCache is an object that allows the programmatic loading of schemas and association of those schemas with a namespace URI. When a document sees a namespace URI and looks for a schema, the first place it looks is the SchemaCache associated with the document. Therefore, a SchemaCache can be used to override x-schema external references as well as x-schema:# internal references.


XDR Schemas and Namespaces

The Microsoft® XML Parser (MSXML 2.0 or later) enables XML-Data Reduced (XDR) schemas to be referenced directly from a namespace declaration. This allows the MSXML parser to validate the XML document against the rules or grammar defined in the schema.

It also allows the object model to expose data types and to allow navigation to the schema document through the definition property. For more information, see XDR Schemas and the DOM.

A namespace declaration can reference a schema by including the URL to the schema document prefaced by the "x-schema:" string. For example, to reference an XDR schema for books from an XML file conforming to this schema, write the following.

<book xmlns="x-schema:http://www.microsoft.com/xml/schema/book.xml">
  <title>Presenting XML</title>
  <author>Richard Light</author>
  <pages>334</pages>
</book>

Here the default namespace refers to the sample book grammar used in the Defining Elements and Attributes section. The namespace Uniform Resource Identifier (URI) is prefixed with "x-schema:" to indicate to MSXML that there is a schema corresponding to this namespace. The remainder of the URI is the schema's location. The path or URI to the schema file must be valid, or a parse error will occur. A schema can also be created as part of the XML document. For the sample book grammar, see Defining Elements and Attributes.

See Also

namespaces Property | schemas Property | Using Inline Schemas


Using Inline Schemas

Instead of using an external schema file, the Microsoft® XML Parser (MSXML) 3.0 or later allows you to use inline schemas. These schemas are useful when it is inconvenient to physically separate the schema and the instance (XML document). For example, if you generate XDR schema from data retrieved from a database, it may be more convenient to put the schema and the data in the same file.

Note Inline schemas are not supported in MSXML 2.5 and earlier versions. To avoid an error on the root element, use the Xmlinst.exe "Replace Mode Tool" available from http://msdn.microsoft.com/downloads/default.asp?URL=/code/sample.asp?url=/msdn-files/027/001/469/msdncompositedoc.xml

Example

The following XML document contains an inline schema against which the <Student> element is validated. The name of the schema, mySchema is indicated through the name attribute on the Schema element.

<Root>
<Schema name="mySchema" xmlns="urn:schemas-microsoft-com:xml-data"
             xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <ElementType name="age" dt:type="int"/>
   <ElementType name="Student" model="closed" content="eltOnly">
     <element type="age"/>
   </ElementType>
</Schema>

Data file

<a:Student xmlns:a="x-schema:#mySchema">
   <a:age>10</a:age>
</a:Student>
</Root>

An element is associated with an inline schema just as it is with an external schema, through the "x-schema:" syntax when defining that element's namespace identifier. For an external schema, the URI or URL that follows "x-schema:" indicates the location of the external schema file. With an inline schema, that which follows "x-schema:" indicates the name of the schema within the XML instance document (indicated by the # sign followed by the name).

The "#" syntax following "x-schema:" refers to a schema within the local document only. This syntax cannot be used to reference a schema within an external document. For example, "x-schema:URI#name" is not allowed.

The inline schema associated with an element must precede that element within the document. When validating against a schema, if the name indicated through an element's namespace declaration does not correspond to an already parsed schema, an error will occur. An error will also occur when an element is associated with a schema that does not exist.

Inline Schemas Persisted from ADO

You can use MSXML 3.0 to parse inline schemas produced by Microsoft ActiveX® Data Objects (ADO), but they will not be validated.

Example

<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
   xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'
   xmlns:rs='urn:schemas-microsoft-com:rowset'
   xmlns:z='#RowsetSchema'>
<s:Schema id='RowsetSchema'>
   <s:ElementType name='row'>
      <s:attribute type='CustomerID'/>
      <s:extends type='rs:rowbase'/>
   </s:ElementType>
<s:AttributeType name='CustomerID' rs:number='1'
   rs:nullable='true' rs:write='true'>
   <s:datatype dt:type='string' dt:maxLength='5'/>
</s:AttributeType>
</s:Schema>
<rs:data>
   <z:row CustomerID='…'/>
</rs:data>
</xml>

MSXML 3.0 essentially ignores the following elements and attributes, and the remainder of the schema is parsed as if it were a valid schema.

Elements | Attributes
extends | dt:max
 | dt:maxExclusive
 | dt:maxLength
 | dt:min
 | dt:minExclusive

Validation against the remainder of the schema cannot occur because the schema does not contain a name attribute and because the reference to the schema is not prefaced by "x-schema:". MSXML 3.0 views that reference as a Uniform Resource Name (URN) with no special significance.

See Also

definition Property | validateOnParse Property


Representing the XDR Schema as a DTD

The following is an example of representing the XML-Data Reduced (XDR) schema with a document type definition (DTD). However, the representation is not exact.

  • Schemas and DTDs use different content models. When the model is defined as open, the element can include ElementType elements, AttributeType elements, and mixed content not specified in the content model. When the model is defined as closed, the element cannot include elements or mixed content not specified in the content model. The DTD uses a closed content model; schemas use an open content model.
  • Possible data types for elements and attributes are different. In the following code sample, the data types parameter, <entity>, lists the data types for both the attributes and elements of the dt:type attribute for the datatype element. MSXML 2.0 and later, support for these data types is limited. The attributes only support the first 10 types (which map to DTD attribute types) and elements only support from "string" through uuid; therefore an element cannot behave like an id or idref.
  • Placement of xmlns namespace declarations cannot be modeled very well using a DTD. In a real schema, the xmlns:dt attributes can go anywhere. Any other xmlns declaration can also appear because schemas follow an open content model. This way you can add extended information in your schemas for your own use.
  • The maxOccurs attribute can only have the values "1" or "*" and this cannot be modeled using a DTD enumeration because "*" is not a valid name token.
  • ElementTypes and AttributeTypes elements can only have one datatype child element. DTDs cannot model this sort of ordinality, particularly when other child elements are allowed.
<!--
  The possible element datatypes according to
    http://msdn.microsoft.com/xml/schema/reference/datatypes.asp
-->
<!ENTITY % datatypes "(entity | entities | enumeration | id | idref | idrefs
| nmtoken | nmtokens | notation | string | bin.base64 | bin.hex | boolean |
char | date | dateTime | dateTime.tz | fixed.14.4 | float | int | number |
time | time.tz | i1 | i2 | i4 | r4 | r8 | ui1 | ui2 | ui4 | uri |
uuid)" >
<!--  *** datatype **** -->
<!ELEMENT datatype  (description)*>
<!ATTLIST datatype
    dt:type %datatypes;  #IMPLIED
    xmlns:dt CDATA #FIXED "urn:schemas-microsoft-com:datatypes"
>
<!--  ***** description  ***** -->
<!ELEMENT description (#PCDATA) >
<!-- ****  element  ***** -->
<!-- additional constraint on maxOccurs is that it must be 1 or "*" -->
<!ELEMENT element  (description)* >
<!ATTLIST element
   type IDREF        #REQUIRED
   minOccurs  CDATA  #IMPLIED
   maxOccurs  CDATA  #IMPLIED
>
<!-- ****  attribute   ***** -->
<!ELEMENT attribute  (description)* >
<!ATTLIST attribute
   type       IDREF    #REQUIRED
   default    CDATA        #IMPLIED
   required   (yes | no)   "no"
>
<!-- ****  AttributeType   ***** -->
<!ELEMENT AttributeType (datatype | description)* >
<!ATTLIST AttributeType
   name         ID              #REQUIRED
   default      CDATA           #IMPLIED
   dt:type      %datatypes;     #IMPLIED
   dt:values    CDATA           #IMPLIED
   required     (yes | no)      #IMPLIED
   xmlns:dt CDATA #FIXED "urn:schemas-microsoft-com:datatypes"
>
<!-- ****  ElementType   ***** -->
<!ELEMENT ElementType (datatype | description | AttributeType | attribute | element | group)* >
<!ATTLIST ElementType
   name  ID                       #REQUIRED
   model (open | closed)          #IMPLIED
   content (empty | textOnly | eltOnly | mixed) #IMPLIED
   order   (one | seq | many)     #IMPLIED
   dt:type %datatypes;            #IMPLIED
   dt:values  CDATA               #IMPLIED
   required  (yes | no)           #IMPLIED
   xmlns:dt CDATA #FIXED "urn:schemas-microsoft-com:datatypes"
>
<!-- ****  group   ***** -->
<!ELEMENT group  (group | element | description)*>
<!ATTLIST group
   minOccurs   CDATA              #IMPLIED
   maxOccurs   CDATA              #IMPLIED
   order      (one | seq | many)  #IMPLIED
>
<!-- ****  Schema   ***** -->
<!ELEMENT Schema  (AttributeType | ElementType | description )* >
<!ATTLIST Schema
   name  CDATA #IMPLIED
   xmlns:dt CDATA #FIXED "urn:schemas-microsoft-com:datatypes"
>


XDR Schema Reference

The Microsoft® XML Parser (MSXML) 2.0 and later versions include support for the XML-Data Reduced Language (XDR).

XDR is based on the World Wide Web Consortium (W3C) XML-Data Note. XDR is implemented as a subset of the XML-Data submission that corresponds to the feature set proposed for Document Content Description (DCD) for XML.

Microsoft is actively involved in defining the emerging W3C XML schema standard, XML Schema Definition language (XSD). MSXML and several other Microsoft products, such as Microsoft Biztalk™ Server, Microsoft Office 2000, and Microsoft SQL Server™ 2000, continue to support XDR.

Unlike the unique document type definition (DTD) syntax, XDR allows you to define the rules governing the relations between elements and attributes using a standard XML instance syntax, which can be parsed and managed using XML applications. XDR also adds support for namespaces, data types, and features like range constraints.

The definitions in an XDR schema are contained within the top-level Schema element. The Schema element definition must come from the namespace xmlns="urn:schemas-microsoft-com:xml-data." The namespace declaration is an XML processing instruction as defined in the W3C Namespace in XML. It is convenient to make the "Schema" namespace the default namespace to avoid having to prefix all definitions within a schema. This documentation uses the convention in which the "Schema" namespace is the default namespace and omits a prefix from all XDR Schema element and attribute names.

The Schema element in an XDR Schema document should also contain namespace declarations for any other schemas, such as the namespace that defines the built-in data types for XDR Schema.

<Schema name="myschema" xmlns="urn:schemas-microsoft-com:xml-data"
                        xmlns:dt="urn:schemas-microsoft-com:datatypes">
 <!-- ... -->
</Schema>

The Schema element can contain any number of top-level declarations. The principal XDR Schema elements include ElementType (XDR) (which declares element types) and AttributeType (XDR) (which declares attribute types). These elements must have an explicit name attribute that is unique within the schema. The element (XDR) and attribute (XDR) elements can appear within the ElementType element to constrain the content and attributes that can appear in elements of the named type. The ElementType attribute order and the group element allow you to further establish fine-grained definitions. The minOccurs and maxOccurs attributes allow you to define the number of occurrences of an element or group.

The content for an element of a given element type can be defined as one of four categories: empty (no content), text only, subelements only, or a mix of text and subelements. This choice is expressed in the ElementType attribute named content, which can take the values "empty," "textOnly," "eltOnly," and "mixed," respectively.

Element types and attribute types can constrain their values and contents to be instances of a particular data type, referenced from the datatype element (XDR) namespace. To use the datatype namespace in a schema, it must be declared within the Schema element. The dt:type attribute can then be used to reference data types; in the Microsoft Internet Explorer 5.0 and later implementation, element and attribute types can take "rich" data types. For more information about data types, see XML Data Types Reference.

See Also

ElementType Element | AttributeType Element | element Element | attribute Element | datatype Element | XDR Data Types Reference | XDR Schema Developer's Guide | XML Reference | Schema Element

Other Resources Other Resources

XML-Data Note | Document Content Description for XML | Namespaces in XML Recommendation


XDR Schema Elements

The following table describes the XDR schema elements.

attribute | Refers to a declared attribute type that can appear within the scope of the named ElementType element.
AttributeType | Defines an attribute type for use within the Schema element.
datatype | Specifies the data type for the ElementType or AttributeType element.
description | Provides documentation about an ElementType or AttributeType element.
element | Refers to a declared element type that can appear within the scope of the named ElementType element.
ElementType | Defines an element type for use within the Schema element.
group | Organizes content into a group to specify a sequence.
Schema | Identifies the start of a schema definition.

XDR Data Types Support

MSXML 2.0 and later provides support for XDR data types. For more information, see XDR Data Types Reference.

See Also

XDR Data Types Reference


attribute Element

Refers to a declared attribute type that can appear within the scope of the named ElementType element.

<attribute
  default="default-value"
  type="attribute-type"
  [required="{yes | no}"]>

Attributes

default
The default value for the attribute. This specified default takes precedence over any default provided on the AttributeType element it refers to.
type
The name of an AttributeType element defined in this schema (or another schema indicated by the specified namespace). The supplied value must correspond to the name attribute on the AttributeType element. The type can include a namespace prefix.
required
An indicator of whether the attribute must be present on the element. Optional if the required attribute is present on the referenced AttributeType.

Element Information

Number of occurrences | Number of attribute types specified in the schema.
Parent elements | ElementType
Child elements | (No child elements)

Remarks

When the required attribute is set to "yes" and the default attribute specifies a default value, the supplied default value must always be the value, and documents containing other attribute values are invalid.

When the required attribute is set to "yes" and no default is specified, each element whose type is declared to have the attribute must supply its value.

See Also

AttributeType element (XDR)


AttributeType Element

Defines an attribute type for use within the Schema element.

<AttributeType
    default="default-value"
    dt:type="primitive-type"
    dt:values="enumerated-values"
    name="idref"
    required="{yes | no}">

Attributes

default
The default value for the attribute. The default value must be legal for that attribute instance. For example, when the attribute is an enumerated type, the default value must appear in the values list.
dt:type
The data type for this attribute type. In the implementation provided with Microsoft® Internet Explorer 5.0, an attribute can take one of the following types: entity, entities, enumeration, id, idref, idrefs, nmtoken, nmtokens, notation, or string. When the type "enumeration" is selected, the dt:values attribute should also be supplied, listing the allowed values. For more information about data types, see XDR Data Types Reference.
dt:values
A list of the possible values when dt:type is set to "enumeration".
name
The name of the attribute type. This attribute is required. References to this attribute type within an ElementType definition are made in the schema with the attribute element. The name supplied here corresponds to the type attribute of the attribute element.
required
An indicator of whether the attribute must be present on the element.

Element Information

Number of occurrences | Unlimited
Parent elements | ElementType, Schema
Child elements | Datatype, description

Element Properties

TAG | Explanation
Name="idref" | ElementTypes and AttributeTypes must have names.
Model="open" | Elements or mixed content not specified in content model is permitted in this element. Note, to subclass a particular definition, it must be open (when inheritance is implemented in the future).
Model="closed" | Elements or mixed content not specified in content model is not permitted in this element.
required='yes' | This attribute must occur. If a default value is also given, then the value must match the default.
dt:values | Specifies the values for enumeration types.
default | Specification of default value for attribute. This can apply to (virtually?) any type of attribute. The default value must be legal for that attribute instance. E.g., in enumeration the default value must appear in the values list.

Remarks

An AttributeType declaration contained within an ElementType element defines that attribute type within the scope of the ElementType that contains it.

In XDR schema, as in XML 1.0, the order of appearance of attributes in an element is not constrained and a given attribute can appear no more than once in an element.

Example

The following example shows an enumeration and its DTD equivalent.

<AttributeType name="colors" dt:type="enumeration"
  dt:values="red green blue">
<!ATTLIST x colors (red | green | blue)>

Example

The following example declares an attribute type called "myattr." This declaration constrains "myattr" attributes to contain only a name token.

<AttributeType name="myattr" dt:type="nmtoken"/>

See Also

XDR Data Types Reference | attribute element (XDR)


datatype Element

Specifies the data type for the ElementType or AttributeType element.

<datatype
  dt:type="datatype">

Attributes

dt:type
The data type.
<ElementType name="colors">
  <datatype dt:type="char"/>
</ElementType>

Element Information

Number of occurrences | One time.
Parent elements | AttributeType, ElementType
Child elements | (No child elements)

Remarks

The datatype functionality is an extension offered by the XML-Data Reduced Langaage (XDR) that cannot be specified using the document type definition (DTD) syntax.

See Also

XDR Data Types Reference


description Element

Provides documentation about an ElementType or AttributeType element.

<description>

Element Information

Number of occurrences | One time.
Parent elements | AttributeType, ElementType, Schema, group, element, attribute
Child elements | Any well-formed XML content.

Remarks

Information supplied within the description element is not used in validation, but provides a standardized way to supply information that can be retrieved by tools.

Example

The following example shows use of the description element providing information about the element.

<ElementType name="Book">
  <description>
  This is how we describe the books we sell. Be sure to specify
  ageGroup!
  </description>
  <element type="ageGroup">
    <default>ADULT</default>
  </element>
</ElementType>


element Element (XDR)

Refers to a declared element type that can appear within the scope of the named ElementType element.

<element
  type="element-type"
  [minOccurs="{0 | 1}"]
  [maxOccurs="{1 | *}"]
>

Attributes

type
The name of an ElementType element defined in this schema (or another schema indicated by the specified namespace). The supplied value must correspond to the name attribute on the ElementType element. The type can include a namespace prefix.
minOccurs
Optional. Minimum number of times the reference element type can occur on the element. The following values can be assigned to this attribute.

0 | When the minimum value is zero, the specified element is not required; the element is optional.
1 | The specified element must occur at least once.

maxOccurs
Optional. Maximum number of times the element can occur on the element. The following values can be assigned to this attribute.

1 Can occur at most once.
* Unlimited number of occurrences.

Element Information

Number of occurrences | Number of element types defined in the schema.
Parent elements | ElementType, group
Child elements | (No child elements)

Remarks

ElementType declarations can constrain the content and attributes that appear in elements of the named type by referring to other element type or attribute type declarations.

The minOccurs and maxOccurs attributes have the default value "1." An element with neither attribute specified uses these default values and therefore must appear once and only once in a content model.


ElementType Element

Defines an element type for use within the Schema element.

<ElementType
  content="{empty | textOnly | eltOnly | mixed}"
  dt:type="datatype"
  model="{open | closed}"
  name="idref"
  order="{one | seq | many}">

Attributes

content
An indicator of whether the content must be empty or can contain text, elements, or both. The following values can be assigned to this attribute. The default value for the content attribute is "mixed." When the content attribute is set to "mixed", the order attribute requires a "many" value.

empty | The element cannot contain content.
textOnly | The element can contain only text, not elements. If the model attribute is set to "open," the element can contain text and other unnamed elements.
eltOnly | The element can contain only the specified elements. It cannot contain any free text.
mixed | The element can contain a mix of named elements and text. Mixed is the default value. If the value of the content attribute is mixed, minOccurs and maxOccurs attributes will not trigger a validation error if the number of child elements is outside the specified boundary.

Example

The following example shows use of the content attribute with different values.

<ElementType name="x" content="empty"/>
<ElementType name="x" content="textOnly"/>
<ElementType name="x" content="eltOnly">
  <element type="y"/>
</ElementType>
<ElementType name="x" content="mixed">
  <element type="q"/>
  <element type="r"/>
</ElementType>

Example

The following example shows the content attribute for an equivalent document type definition (DTD).

empty: <!ELEMENT x EMPTY>
textOnly: <!ELEMENT x (#PCDATA)>
eltOnly: <!ELEMENT x y>
mixed: <!ELEMENT x (#PCDATA | q | r)*>
dt:type
The data type of the element. The valid data types are defined in the XDR Data Types Reference.
model
An indicator of whether the content can include only what is defined in the content model or can contain content not specified in the model. Default is "open."
<ElementType name="x" model="open"/>

When the model is defined as open, the element can include additional elements or attributes not declared explicitly in the content model. These additional tags can come from the same namespace or a different namespace. If they are in the same namespace, there must be a corresponding ElementType or AttributeType definition for them in the schema.

When the model is defined as closed, the element cannot include elements and cannot include mixed content not specified in the content model. The DTD uses a closed model.

name
The name of the element. This attribute is required. If this element type is declared as a valid child of another element type, this name is specified within an element element.
<ElementType name="x">
</ElementType>

The DTD equivalent is as follows.

<!ELEMENT x EMPTY>
order
An indicator of how the elements are to appear. This indicator can have the following values.

one | Permits only one of a set of elements. For a document to correctly validate when the one attribute is specified, the model attribute for the ElementType must be specified as "closed."
seq | Requires the elements to appear in the specified sequence.
many | Permits the elements to appear (or not appear) in any order. If you specify "many" for the order attribute, maxOccurs values are no longer relevant during validation.

The "seq" value is required to specify valid sequences. For example, it can be used to specify when a particular sequence, such as "x1,y1" or "x2,y2", is valid but no other possible combinations are valid. The "seq" value serves the same role as parentheses in a DTD. The default value is "seq."

The following example demonstrates the "one" setting. The value of the model attribute must be "closed" when "one" is specified for the order attribute.

<ElementType name="z" content="eltOnly" order="one" model="closed">
<element type="x" minOccurs="1" maxOccurs="1"/>
<element type="y" minOccurs="1" maxOccurs="1"/>
</ElementType>

The following example demonstrates the "seq" setting.

<ElementType name="x" content="eltOnly" order="one" model="closed">
  <group order="seq" content="eltOnly" model="closed">
    <element type="x1"/>
    <element type="y1"/>
  </group>
  <group order="seq" content="eltOnly" model="closed">
    <element type="x2"/>
    <element type="y2"/>
  </group>
</ElementType>

The following example demonstrates the "many" setting.

<ElementType name="x" content="eltOnly" order="many" model="closed">
  <element type="q"/>
  <element type="r"/>
</ElementType>

The "many" setting of the order attribute makes the minOccurs and maxOccurs attributes irrelevant during validation. Rather than using the "many" setting for the order attribute in conjunction with minOccurs and maxOccurs, use the "seq" setting instead. For example, consider the following schema. At the bottom of the sample, order="seq" is set.

<?xml version="1.0"?>
<Schema name="SampleSchema" xmlns="urn:schemas-microsoft-com:xml-data"
    xmlns:dt="urn:schemas-microsoft-com:datatypes">
    <ElementType name="PublisherID" model="closed" dt:type="ID"
      content="textOnly">
    </ElementType>
    <ElementType name="PublisherName" model="closed" dt:type="string"
      content="textOnly">
    </ElementType>

    <ElementType name="Publisher" model="closed" content="eltOnly"
      order="many">
      <element type="PublisherID"/>
      <element type="PublisherName"/>
    </ElementType>

    <ElementType name="Book" model="closed" content="eltOnly"
      order="seq">
    <element type="Publisher" minOccurs="1" maxOccurs="1"/>
    </ElementType>

</Schema>

If the following XML document is validated against the preceding schema, the validation fails because the number of <Publisher> elements exceeds the specified maxOccurs value of "1". However, if the order value is set to "many," the validation will incorrectly succeed because the maxOccurs="1" setting will be ignored.

<?xml version='1.0'?>
<Book xmlns="x-schema:orderschema.xml" >

<Publisher>
    <PublisherID>P1</PublisherID>
    <PublisherName>GG&G</PublisherName>
</Publisher>
<Publisher>
    <PublisherID>P2</PublisherID>
    <PublisherName>North</PublisherName>
</Publisher>

</Book>

Element Information

Number of occurrences | Unlimited
Parent elements | Schema
Child elements | attribute, AttributeType, datatype, description, element, group

Element Properties

TAG | Explanation
Name="idref" | ElementTypes and AttributeTypes elements must have names.
Model="open" | Elements or mixed content not specified in content model is permitted in this element. Note, to subclass a particular definition, it must be open (when inheritance is implemented in the future).
Model="closed" | Elements or mixed content not specified in content model is not permitted in this element.
content="empty" | The element may not contain anything.
content="textOnly" | The element may contain only text, not elements. Note if model='open', then the element may still contain text and other unnamed elements.
* content="mixed" | The element may contain a mixture of named elements and intermingled text. Note if model='open', then the element may still contain text and other unnamed elements. Implies order='many' and maxOccurs="*"!
order='one' | Permits only one of a set of elements.
* order='seq' | Says that the elements must appear in the listed sequence. At first glance this is the same the default for a list of elements, however, this is needed in order to group sequences as per the example, where either x1,y1, or x2,y2 is legal, but no other combinations are. In other words, serves the same role as parenthesis in a DTD.
order='many' | The elements may appear (or not appear) in any order.
dt:type=datatype | Specifies that the element should contain an integer. See DataTypes for a list of primitive data types.

Remarks

The term "element type" refers to the element type of which all elements sharing a name are instances. Element types are declared in schemas; elements occur in documents. Element types are declared with the ElementType element type.

Example

<ElementType name="x">
  <!-- element content declarations go here -->
</ElementType>

See Also

XDR Data Types Reference


group Element (XDR)

Organizes content into a group to specify a sequence.

<group
  maxOccurs="{1 | *}"
  minOccurs="{0 | 1}"
  order="{one | seq | many}" >

Attributes

maxOccurs
The maximum number of times the group can occur. The following values can be assigned to this attribute.

1 Occurs at most once.
* Unlimited number of occurrences.

minOccurs
The minimum number of times the group can occur. The following values can be assigned to this attribute.

0 | Not required; the group is optional.
1 | Must occur at least once.

order
A constraint on the sequence of elements (and other contained groups) within this group. The following values can be assigned to this attribute.

one | Permits only one instance of each element contained in the group. This corresponds to the | symbol in the document type definition (DTD).
seq | Requires the elements in the group to appear in the specified sequence.
many | Permits the elements in the group to appear (or not appear) in any order.

The "seq" setting is required to specify valid sequences. For example, it can be used to specify when a particular sequence, such as "x1,y1" or "x2,y2", is valid but no other possible combinations are valid. The "seq" value serves the same role as parentheses in a DTD.

Element Information

Number of occurrences | Unlimited
Parent elements | ElementType
Child elements | element, description

Element Properties

TAG | Explanation
order='one' | Permits only one of a set of elements.
* order='seq' | Says that the elements must appear in the listed sequence. At first glance this is the same the default for a list of elements, however, this is needed in order to group sequences as per the example, where either x1,y1, or x2,y2 is legal, but no other combinations are. In other words, serves the same role as parenthesis in a DTD.
order='many' | The elements may appear (or not appear) in any order.
minOccurs='0' or '1' maxOccurs='1' or '*' | Allows precise definition of cardinality. '*' on maxOccurs means unlimited.

Remarks

The order attribute takes the same values as the order attribute of the ElementType element.

The minOccurs and maxOccurs attributes have the default value "1." A group with neither attribute must appear once and only once in a content model.

Examples

The following example demonstrates the "one" setting.

<ElementType name="z" order="one">
<element type="x">
<element type="y">
</ElementType>

The following represents a legal instance of the schema.

<z>
  <x/>
  <y></y>
</z>

The following example demonstrates the "seq" setting.

<ElementType name="x" order="one">
  <group order="seq">
    <element type="x1">
    <element type="y1">
  </group>
  <group order="seq">
    <element type="x2">
    <element type="y2">
  </group>
</ElementType>

The following two examples represent legal instances of this schema.

<x>
  <x1/>
  <y1/>
</x>

and:

<x>
  <x2/>
  <y2/>
</x>

The following example demonstrates the "many" setting.

<ElementType name="x" content="eltOnly" order="many">
  <element type="q">
  <element type="r">
</ElementType>

The following five examples represent all legal instances for this schema.

<x> </x>
<x> <q> </x>
<x> <r> </x>
<x> <q> <r> </x>
<x> <r> <q> </x>


Schema Element (XDR)

Identifies the start of a schema definition.

<Schema
  name="schema-name"
  xmlns="namespace">

Attributes

name
Name of the schema.
xmlns
One or more namespaces for use with the schema.

Element Information

Number of occurrences | One time.
Parent elements | (No parent elements)
Child elements | AttributeType, ElementType, description

Remarks

The Schema element is the document element (the highest-level element) in a schema definition.

The namespaces specified using the xmlns attribute must include the namespace for the schema-defining elements (Schema, ElementType, and so on). Any prefix can be used, but it is convenient to make the "Schema" namespace the default namespace to avoid having to use a prefix on every XML Schema element.

The Schema element in an XML Schema should also contain namespace declarations for any other schemas, such as the namespace that defines the built-in data types for XML Schema.

Example

<Schema name="fooSchema" xmlns="urn:schemas-microsoft-com:xml-data"
                    xmlns:dt="urn:schemas-microsoft-com:datatypes">

</Schema>


XDR Data Types Reference

In addition to the string and other primitive types defined by the XML 1.0 recommendation, the Microsoft® XML Parser (MSXML) supports a rich set of additional data types. It also supports conversions between the primitive types and these rich data types.

Data types are referenced from the data type namespace "urn:schemas-microsoft-com:datatypes". To use data types within an XML schema, declare the data type namespace within the schema document. This documentation assumes that the data type namespace has been assigned the "dt" prefix, as shown in the following example.

<Schema name="myschema"
        xmlns="urn:schemas-microsoft-com:xml-data"
        xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <!-- ... -->
</Schema>

See Also

XDR Data Types | Primitive XDR Data Types | Supported Data Type Conversions | XDR Schema Developer's Guide | XDR Schema Reference


XDR Data Types

The following table shows the data types used in XDR schemas.

XDR Data Type | Description | Corresponding type in DTD
bin.base64 | MIME-style Base64 encoded binary BLOB. | Not used
bin.hex | Hexadecimal-encoded binary data. | Not used
boolean | A value of either 0 or 1. Example: 0=="false" and 1=="true"' | Not used
char | A number corresponding to the Unicode representation of a single character. | Not used
date | A date in a subset of the ISO 8601 format, without the time data. Example: "1994-11-05" | Not used
dateTime | A date in a subset of the ISO 8601 format, with optional time and no optional zone. Fractional seconds can be as precise as nanoseconds. Example:"1988-04-07T18:39:09" | Not used
dateTime.tz | A date in a subset of the ISO 8601 format, with optional time and optional zone. Fractional seconds can be as precise as nanoseconds. Example: "1988-04-07T18:39:09-08:00" | Not used
entity | A reference to an unparsed entity. Requires a matching <!ENTITY> declaration for each instance of the entity. | Not used
entities | A list of entities delimited by white space. | Not used
enumeration | Similar to nmtoken, but with an explicit list of allowed values (supported on attributes only). Example: "Red Blue Green" | Enumeration
fixed.14.4 | A number with no more than 14 digits to the left of the decimal point and no more than 4 to the right. Example: 9999.0044 | Not used
float | A real number, with no limit on the digits (2.2250738585072014E-308 - 1.7976931348623157E+308). Example: 111, 3.14, -123.456E+10 | Not used
i1 | A one-byte integer, with optional sign (-128 to 127). Example: 1, 127, -128 | Not used
i2 | A two-byte integer with optional sign (-32768 to 32767). Example: 1, 703, -32768 | Not used
i4 | A four-byte integer with optional sign (-2147483648 to 2147483647). Example: 1, 703, -32768, 148343, -1000000000 | Not used
i8 | An eight-byte integer with optional sign (-9223372036854775808 to 9223372036854775807). For example: 1, 703, -32768, 1483433434334, -1000000000000000 | Not used
id | A value that identifies an attribute as an id type attribute. The id values must be unique throughout the document. In a document, idref(s) attributes refer to an id type attribute, thus forming a relationship similar to primary key and foreign key in relational databases. Example: Cust1 | ID
idref | A value corresponding to an id type, thus enabling intra-document links. Example: Cust1 | IDREF
idrefs | Similar to idref, except it contains multiple id type values separated by white space. Example: Cust1 Cust2 Cust3 | IDREFS
int | A signed integer. Example: 11123, -123 | Not used
nmtoken | Values that conform to the rules of the name token. Example: Cust1 | NMTOKEN
nmtokens | Similar to nmtoken, except it can have a list of nmtoken values separated by white space. Example: Cust1 Cust2 Cust3 | NMTOKENS
notation | A NOTATION type | Not used
number | A number with no limits on the digits (2.2250738585072014E-308 - 1.7976931348623157E+308). Example: 111, 3.14, -123.456E+10 | Not used
r4 | Same as float but only four-byte encoding (1.17549435E-38 - 3.40282347E+38). | Not used
r8, float | A floating point number. This data type only supports 15 digits of precision (2.2250738585072014E-308 - 1.7976931348623157E+308). | Not used
string | A string. Example: "This is a string" | CDATA
time | A time in a subset of the ISO 8601 format with no date and no time zone. Example: "08:15:27" | Not used
time.tz | A time in a subset of the ISO 8601 format with no date but optional time zone. Example: "08:15:27-05:00" | Not used
ui1 | A one-byte unsigned integer (0 to 255). Example: 1, 255 | Not used
ui2 | A two-byte unsigned integer (0 – 65535). Example: 1, 255, 65535 | Not used
ui4 | A four-byte unsigned integer (0 – 4294967296). Example: 1, 703, 3000000000 | Not used
ui8 | An eight-byte unsigned integer (0 – 18446744073709551615). Example: 1483433434334 | Not used
uri | A Uniform Resource Identifier (URI). Example: "urn:schemas-microsoft-com:Office9" | Not used
uuid | Hexadecimal digits representing octets with optional embedded hyphens that are ignored. Example: 333C7BC4-460F-11D0-BC04-0080C7055A83 | Not used

See Also

XDR Data Types Reference | Primitive XDR Data Types | Supported Data Type Conversions | XDR Schema Developer's Guide | XDR Schema Reference


Primitive XDR Data Types

The World Wide Web Consortium (W3C) XML 1.0 Recommendation also defines enumerated types (notations and enumerations) and a set of tokenized types. These types are referred to as "primitive types" in this Microsoft® XML documentation.

The primitive types include the following, defined in Section 3.3.1 of the W3C XML 1.0 Recommendation.

entity | Represents the XML ENTITY type.
entities | Represents the XML ENTITIES type.
enumeration | Represents an enumerated type (supported on attributes only).
id | Represents the XML ID type.
idref | Represents the XML IDREF type.
idrefs | Represents the XML IDREFS type.
nmtoken | Represents the XML NMTOKEN type.
nmtokens | Represents the XML NMTOKENS type.
notation | Represents a NOTATION type.
string | Represents a string type.

See Also

XDR Data Types Reference | XDR Data Types | Supported Data Type Conversions | XDR Schema Developer's Guide | XML Schema Reference


Supported Data Type Conversions

The following table lists the data type conversions supported by the MSXML 2.0 and later.

Data type | Variant type
string | VT_BSTR, VT_BOOL, VT_CY, VT_DATE, VT_VARIANT, VT_DECIMAL, VT_UII, VT_I2, VT_I4, VT_R4, VT_R8, VT_EMPTY, VT_NULL, VT_ARRAY
number | VT_BSTR, VT_BOOL, VT_CY, VT_VARIANT, VT_DECIMAL, VT_UII, VT_I2, VT_I4, VT_R4, VT_R8, VT_EMPTY, VT_NULL
int | VT_BSTR, VT_BOOL, VT_VARIANT, VT_UII, VT_I2, VT_I4, VT_EMPTY, VT_NULL
float | VT_BSTR, VT_CY, VT_VARIANT, VT_DECIMAL, VT_UII, VT_I2, VT_I4, VT_R4, VT_R8, VT_EMPTY, VT_NULL
fixed.14.4 (currency) | VT_BSTR, VT_CY, VT_VARIANT, VT_DECIMAL, VT_UII, VT_I2, VT_I4, VT_R4, VT_EMPTY, VT_NULL
boolean | VT_BSTR, VT_BOOL, VT_VARIANT, VT_DECIMAL, VT_UII, VT_I2, VT_I4, VT_EMPTY, VT_NULL
dateTime | VT_BSTR, VT_DATE, VT_VARIANT
i1 | VT_BSTR, VT_BOOL, VT_VARIANT, VT_DECIMAL, VT_EMPTY, VT_NULL
i2 | VT_BSTR, VT_BOOL, VT_VARIANT, VT_DECIMAL, VT_I2, VT_EMPTY, VT_NULL
i4 | VT_BSTR, VT_BOOL, VT_VARIANT, VT_DECIMAL, VT_I2, VT_I4, VT_EMPTY, VT_NULL
i8 | VT_BSTR, VT_BOOL, VT_CY, VT_VARIANT, VT_DECIMAL, VT_I2, VT_I4
ui1 | VT_BSTR, VT_BOOL, VT_VARIANT, VT_DECIMAL, VT_UI1, VT_EMPTY, VT_NULL
ui2 | VT_BSTR, VT_BOOL, VT_VARIANT, VT_UI1, VT_I2, VT_EMPTY, VT_NULL
ui4 | VT_BSTR, VT_BOOL, VT_VARIANT, VT_UI1, VT_I2, VT_I4, VT_EMPTY, VT_NULL
ui8 | VT_BSTR, VT_BOOL, VT_CY, VT_VARIANT, VT_DECIMAL, VT_UI1, VT_I2, VT_I4, VT_EMPTY, VT_NULL
r4 | VT_BSTR, VT_CY, VT_VARIANT, VT_DECIMAL, VT_I2, VT_I4, VT_R4, VT_EMPTY, VT_NULL
r8 | VT_BSTR, VT_CY, VT_VARIANT, VT_DECIMAL, VT_I2, VT_I4, VT_R4, VT_R8, VT_EMPTY, VT_NULL
uuid | VT_BSTR, VT_VARIANT
uri | VT_BSTR, VT_VARIANT
bin.hex | VT_BSTR, VT_VARIANT, VT_ARRAY
char | VT_BSTR, VT_VARIANT, VT_I2, VT_EMPTY, VT_NULL

See Also

XDR Data Types Reference | XDR Data Types | Primitive XDR Data Types | XDR Schema Developer's Guide | XDR Schema Reference


XML Reference

This section of the XML SDK documentation contains the following references.

  • XML DOM Objects/Interfaces
  • XML DOM Properties
  • XML DOM Methods
  • XML DOM Events
  • XML DOM Enumerated Constants
  • XML Helper Objects/Interfaces
  • XML Helper Methods
  • XML Helper Properties
  • XML Error Messages

The XML Document Object Model (DOM) Reference documentation is provided for script, Microsoft® Visual Basic®, and C/C++ developers.

You can filter the documentation, language specific remarks, and example code by clicking the language filter icon in each topic and selecting a language. Selecting Show All will display all languages with specific references marked for the specific language.

The following Books.xml file is used in examples throughout the XML Reference.

<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications with XML.</description>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description>
</book>
<book id="bk103">
<author>Corets, Eva</author>
<title>Maeve Ascendant</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-11-17</publish_date>
<description>After the collapse of a nanotechnology society in England, the young survivors lay the foundation for a new society.</description>
</book>
<book id="bk104">
<author>Corets, Eva</author>
<title>Oberon's Legacy</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2001-03-10</publish_date>
<description>In post-apocalypse England, the mysterious agent known only as Oberon helps to create a new life for the inhabitants of London. Sequel to Maeve Ascendant.</description>
</book>
<book id="bk105">
<author>Corets, Eva</author>
<title>The Sundered Grail</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2001-09-10</publish_date>
<description>The two daughters of Maeve, half-sisters, battle one another for control of England. Sequel to Oberon's Legacy.</description>
</book>
<book id="bk106">
<author>Randall, Cynthia</author>
<title>Lover Birds</title>
<genre>Romance</genre>
<price>4.95</price>
<publish_date>2000-09-02</publish_date>
<description>When Carla meets Paul at an ornithology conference, tempers fly as feathers get ruffled.</description>
</book>
<book id="bk107">
<author>Thurman, Paula</author>
<title>Splish Splash</title>
<genre>Romance</genre>
<price>4.95</price>
<publish_date>2000-11-02</publish_date>
<description>A deep sea diver finds true love twenty thousand leagues beneath the sea.</description>
</book>
<book id="bk108">
<author>Knorr, Stefan</author>
<title>Creepy Crawlies</title>
<genre>Horror</genre>
<price>4.95</price>
<publish_date>2000-12-06</publish_date>
<description>An anthology of horror stories about roaches, centipedes, scorpions  and other insects.</description>
</book>
<book id="bk109">
<author>Kress, Peter</author>
<title>Paradox Lost</title>
<genre>Science Fiction</genre>
<price>6.95</price>
<publish_date>2000-11-02</publish_date>
<description>After an inadvertant trip through a Heisenberg Uncertainty Device, James Salway discovers the problems of being quantum.</description>
</book>
<book id="bk110">
<author>O'Brien, Tim</author>
<title>Microsoft .NET: The Programming Bible</title>
<genre>Computer</genre>
<price>36.95</price>
<publish_date>2000-12-09</publish_date>
<description>Microsoft's .NET initiative is explored in detail in this deep programmer's reference.</description>
</book>
<book id="bk111">
<author>O'Brien, Tim</author>
<title>MSXML3: A Comprehensive Guide</title>
<genre>Computer</genre>
<price>36.95</price>
<publish_date>2000-12-01</publish_date>
<description>The Microsoft MSXML3 parser is covered in detail, with attention to XML DOM interfaces, XSLT processing, SAX and more.</description>
</book>
<book id="bk112">
<author>Galos, Mike</author>
<title>Visual Studio 7: A Comprehensive Guide</title>
<genre>Computer</genre>
<price>49.95</price>
<publish_date>2001-04-16</publish_date>
<description>Microsoft Visual Studio 7 is explored in depth, looking at how Visual Basic, Visual C++, C#, and ASP+ are integrated into a comprehensive development environment.</description>
</book>
</catalog>


XML DOM Objects/Interfaces

This part of the XML Document Object Model (DOM) reference describes the programming object syntax.

[Script, Visual Basic, C/C++]

The first table lists the core objects/interfaces, followed by a table listing the implemented objects/interfaces.

XML DOM Core Objects/Interfaces

The following objects/interfaces represent implementations of the XML DOM core objects/interfaces. The objects/interfaces include Microsoft extensions to support namespaces, data types, XML schemas, Extensible Stylesheet Language (XSL), XSL Transformations (XSLT) operations, asynchronous loading, and saving documents.

IXMLDOMDocument/DOMDocument | Represents the top node of the XML DOM tree.
IXMLDOMDocument2 | Extension of DOMDocument that supports schema caching, runtime validation, and a way to switch on XML Path Language (XPath) support.
IXMLDOMNamedNodeMap | Provides iteration and access by name to the collection of attributes. IXMLDOMNamedNodeMap includes support for namespaces.
IXMLDOMNode | Represents a single node in the document tree; the base interface for accessing data in the XML object model. IXMLDOMNode includes support for data types, namespaces, document type definitions (DTDs), and XML schemas.
IXMLDOMNodeList | Supports iteration and indexed access operations on the live collection of IXMLDOMNode.
IXMLDOMParseError | Returns detailed information about the last error, including the error number, line number, character position, and a text description.
IXMLHTTPRequest | Provides client-side protocol support for communication with HTTP servers.
IXTLRuntime | Implements methods that can be called from XSLT style sheets.

XML DOM Implemented Objects/Interfaces

The following table represents implementations of other XML DOM interfaces.

IServerXMLHTTPRequest/ServerXMLHTTP | Provides methods and properties that enable you to establish an HTTP connection between files or objects on different Web servers. It is derived from IXMLHTTPRequest.
IXMLDOMAttribute | Represents an attribute.
IXMLDOMCDATASection | Quotes or escapes blocks of text so that text is not interpreted as markup language.
IXMLDOMCharacterData | Provides text manipulation methods used by several objects.
IXMLDOMComment | Represents the content of an XML comment.
IXMLDOMDocumentFragment | Represents a lightweight object that is useful for tree insert operations.
IXMLDOMDocumentType | Contains information associated with the document type declaration.
IXMLDOMElement | Represents the element.
IXMLDOMEntity | Represents a parsed or unparsed entity in the XML document.
IXMLDOMEntityReference | Represents an entity reference node.
IXMLDOMImplementation | Provides methods that are independent of any particular instance of the document object model.
IXMLDOMNotation | Contains a notation declared in the DTD or schema.
IXMLDOMProcessingInstruction | Represents a processing instruction, which XML defines to keep processor-specific information in the text of the document.
XMLSchemaCache | Represents a set of namespace URIs.
IXMLDOMSchemaCollection | Represents a SchemaCache object.
IXMLDOMSelection | Represents a list of nodes that match an XSL Pattern or XPath expression.
IXMLDOMText | Represents the text content of an element or attribute.
IXSLProcessor | Used for performing transformations with cached XSL templates.
IXSLTemplate | Represents a cached XSL style sheet.

For a list of all valid node types, see XML DOM Enumerated Constants.

[C/C++]

Implementing header files

If you have Microsoft Internet Explorer 5.0 or Microsoft Internet Explorer 5.5 installed, you can download the interface header files from MSDN®.

To download the header files

  1. Under Web & Internet Samples TOC, click Headers and Libraries.
  2. Click Internet Explorer 5.01 Headers & Libraries or Internet Explorer 5.5 Headers & Libraries. Then follow the on-screen instructions on how to download these headers and libraries. Save them to C:\Workshop.
  3. Repeat step 2 for Win32 Headers & Libraries for Windows 2000.
  4. Start Visual C++. On the Tools menu, click Options.
  5. Click on the Directories tab, and then add C:\Workshop\Include and C:\Workshop\Include\NT5 to the top of the Directories list.
  6. In the Show Directories for box, select Library files.
  7. Add C:\Workshop\Lib and C:\Workshop\Lib\NT5 to the top of the Directories list.

Other Resources Other Resources

Web & Internet Samples


IXMLDOMAttribute

Represents an attribute of the IXMLDOMElement. Valid and default values for the attribute are defined in a document type definition (DTD) or schema.

[Script]

Example

The following script example creates an IXMLDOMAttribute object from the first attribute of the root and displays the object's value and xml properties.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var objDOMatt;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
objDOMatt = root.firstChild.attributes.item(0);
alert(objDOMatt.value);
alert(objDOMatt.xml);
[Visual Basic]

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMAttribute object from the first attribute of the root and displays the object's value and xml properties.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim objDOMatt As IXMLDOMAttribute
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
Set objDOMatt = root.firstChild.Attributes.Item(0)
MsgBox (objDOMatt.Value)
MsgBox (objDOMatt.xml)
[C/C++]

Example

#import "msxml4.dll"
using namespace MSXML2;

#define CHECK_AND_RELEASE(pInterface)  \
if(pInterface) \
{\
pInterface->Release();\
pInterface = NULL;\
}\

#define RELEASE(pInterface)  \
{\
pInterface->Release();\
pInterface = NULL;\
}\

_variant_t varValue;
BSTR bstrAttributeName = ::SysAllocString(_T("dateCreated"));
IXMLDOMElement *pIXMLDOMElement = NULL;
IXMLDOMDocument *pIXMLDOMDocument = NULL;
HRESULT hr;

try
{
   // Initialize pIXMLDOMDocument and load an
   // XML file into it.
   // Get the document root.
   hr = pIXMLDOMDocument->get_documentElement( &pIXMLDOMElement);
   SUCCEEDED(hr) ? 0 : throw hr;
   if(pIXMLDOMElement)
   {
      varValue = _T("year 2000");
      hr = pIXMLDOMElement->setAttribute(bstrAttributeName, varValue);
      SUCCEEDED(hr) ? 0 : throw hr;

      hr = pIXMLDOMElement->getAttribute(bstrAttributeName, &varValue);
      SUCCEEDED(hr) ? 0 : throw hr;

      if(varValue.vt != VT_NULL)
      {
         ::MessageBox(NULL, _bstr_t(varValue), bstrAttributeName, MB_OK);
         bResult = TRUE;
      }
      RELEASE(pIXMLDOMElement);
   }
   ::SysFreeString(bstrAttributeName);
   bstrAttributeName=NULL;
}
catch(...)
{
   if(bstrAttributeName)
   {
      ::SysFreeString(bstrAttributeName);
      bstrAttributeName = NULL;
   }
   CHECK_AND_RELEASE(pIXMLDOMElement);
   DisplayErrorToUser();
}
// Release pIXMLDOMDocument when finished with it.

Output (in a message box)

Year 2000

Remarks

Attribute nodes cannot be the immediate children of IXMLDOMDocumentFragment. However, they can be associated with element nodes that are children of IXMLDOMDocumentFragment node.

The relationship between the value and specified members can be summarized as follows: If the attribute has an assigned value in the document and the specified member is True, the value is the assigned value. If the attribute has no assigned value in the document and has a default value in the DTD, the specified member is False and the value is the default value in the DTD. If the attribute has no assigned value in the document and has a value of #IMPLIED in the DTD, the attribute does not appear in the structure model of the document.

In XML, the value of an attribute is represented by the child nodes of the attribute node because the value can contain entity references. Thus attributes that contain entity references will have a child list containing both text nodes and entity reference nodes. In addition, because the attribute type might be unknown, there are no tokenized attribute values.

[C/C++]

IXMLDOMAttribute inherits IXMLDOMNode but are not actually child nodes of the element and are not considered part of the document tree. Attributes are considered members of their associated elements rather than independent and separate. Thus IXMLDOMAttribute parentNode, previousSibling, and nextSibling members have the value Null.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

Inherits From: IXMLDOMNode

See Also

IXMLDOMAttribute Members | IXMLDOMElement | IXMLDOMDocumentFragment | value Property | specified Property | IXMLDOMNode | parentNode Property | previousSibling Property | nextSibling Property


IXMLDOMAttribute Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IXMLDOMNode.

Properties

attributes | Contains the list of attributes for this node. Read-only.
baseName* | Returns the base name for the name qualified with the namespace. Read-only.
childNodes | Contains a node list containing the children nodes. Read-only.
dataType* | Specifies the data type for this node. Read/write.
definition* | Returns the definition of the node in the document type definition (DTD) or schema. Read-only.
firstChild | Contains the first child of the node. Read-only.
lastChild | Returns the last child node. Read-only.
name | Contains the attribute name. Read-only.
namespaceURI* | Returns the Uniform Resource Identifier (URI) for the namespace. Read-only.
nextSibling | Contains the next sibling of this node in the parent's child list. Read-only.
nodeName | Contains the qualified name of the element, attribute, or entity reference, or a fixed string for other node types. Read-only.
nodeType | Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes. Read-only.
nodeTypedValue* | Contains the node value expressed in its defined data type. Read/write.
nodeTypeString* | Returns the node type in string form. Read-only.
nodeValue | Contains the text associated with the node. Read/write.
ownerDocument | Returns the root of the document that contains the node. Read-only.
parentNode | Contains the parent node. Read-only.
parsed* | Indicates the parsed status of the node and child nodes. Read-only.
prefix* | Returns the namespace prefix. Read-only.
previousSibling | Contains the previous sibling of this node in the parent's child list. Read-only.
specified | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the document type definition (DTD) or schema. Read-only.
text | Represents the text content of the node or the concatenated text representing the node and its descendants. Read/write.
value | Contains the attribute value. Read/write.
xml | Contains the XML representation of the node and all its descendants. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) DOM.

Methods

appendChild | Appends new child node as the last child of this node.
cloneNode | Clones a new node.
hasChildNodes | Provides a fast way to determine whether a node has children.
insertBefore | Inserts a child node to the left of the specified node or at the end of the list.
removeChild | Removes the specified child node from the list of children and returns it.
replaceChild | Replaces the specified old child node with the supplied new child node.
selectNodes | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
selectSingleNode | Applies the specified pattern-matching operation to this node's context and returns the first matching node.
transformNode | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation.
transformNodeToObject | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation in the supplied object.

Events

None.

See Also

IXMLDOMNode


IXMLDOMCDATASection

Used to quote or escape blocks of text to keep that text from being interpreted as markup language.

[C/C++]

Although the IXMLDOMCDATASection inherits IXMLDOMText, unlike text nodes, the normalize method of IXMLDOMElement does not merge CDATASection nodes.

[Script]

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root, nodeCDATA;
nodeCDATA = xmlDoc.createCDATASection("Hello");
alert(nodeCDATA.xml);
[Visual Basic]

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim nodeCDATA As IXMLDOMCDATASection
Set nodeCDATA = xmlDoc.createCDATASection("Hello")
MsgBox nodeCDATA.xml
[C/C++]

Example

The following C/C++ example creates and appends a new CDATASection node to the root document element.

#import "msxml4.dll"
using namespace MSXML2;

inline void TESTHR( HRESULT _hr )
   { if FAILED(_hr) throw(_hr); }

void XMLDOMCDATASectionSample()
{
   try {
      IXMLDOMDocumentPtr docPtr;
      IXMLDOMNodePtr DOMNodePtr;

      //init
      TESTHR(CoInitialize(NULL));
      TESTHR(docPtr.CreateInstance("msxml2.domdocument"));

      // load a document
      _variant_t varXml("C:\\book.xml");
      _variant_t varOut((bool)TRUE);
      varOut = docPtr->load(varXml);
      if ((bool)varOut == FALSE)
         throw(0);
      MessageBox(NULL, _bstr_t(docPtr->xml), _T("Original Document"), MB_OK);

      DOMNodePtr = docPtr->createCDATASection("<fragment>XML tags
inside a CDATA section</fragment>");
      docPtr->documentElement->appendChild(DOMNodePtr);

      MessageBox(NULL, _bstr_t(docPtr->xml), _T("New Document"), MB_OK);

   } catch(...)
   {
      MessageBox(NULL, _T("Exception occurred"), _T("Error"), MB_OK);
   }
   CoUninitialize();
}

Remarks

CDATA sections let you include material such as XML fragments within XML documents without needing to escape all the delimiters. The only delimiter recognized in a CDATA section is the "]]>" string that ends the CDATA section.

CDATA sections cannot be nested.

The text contained by the CDATA section is stored in a text node. This text can contain characters that need to be escaped outside of CDATA sections.

IXMLDOMCDATASection has no unique members of its own, but exposes the same members as the IXMLDOMText object.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

normalize Method | IXMLDOMCDATASection Members | IXMLDOMElement | IXMLDOMText


IXMLDOMCDATASection Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IXMLDOMText.

Properties

attributes | Contains the list of attributes for this node. Read-only.
baseName* | Returns the base name for the name qualified with the namespace. Read-only.
childNodes | Contains a node list containing the children nodes. Read-only.
data | Stores the node data depending on the node type. Read/write.
dataType* | Specifies the data type for this node. Read/write.
definition* | Returns the definition of the node in the document type definition (DTD) or schema. Read-only.
firstChild | Contains the first child of the node. Read-only.
lastChild | Returns the last child node. Read-only.
length | Specifies the length, in characters, of the data. Read-only.
namespaceURI* | Returns the Uniform Resource Identifier (URI) for the namespace. Read-only.
nextSibling | Contains the next sibling of the node in the parent's child list. Read-only.
nodeName | Contains the qualified name of the element, attribute, or entity reference, or a fixed string for other node types. Read-only.
nodeType | Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes. Read-only.
nodeTypedValue* | Contains the node value expressed in its defined data type. Read/write.
nodeTypeString* | Returns the node type in string form. Read-only.
nodeValue | Contains the text associated with the node. Read/write.
ownerDocument | Returns the root of the document that contains this node. Read-only.
parentNode | Contains the parent node. Read-only.
parsed* | Indicates the parsed status of the node and child nodes.
prefix* | Returns the namespace prefix. Read-only.
previousSibling | Contains the previous sibling of the node in the parent's child list. Read-only.
specified | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the document type definition (DTD) or schema. Read-only.
text* | Represents the text content of the node or the concatenated text representing the node and its descendants. Read/write.
xml* | Contains the XML representation of the node and all its descendants. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) DOM.

Methods

appendChild | Appends a new child node as the last child of the node.
appendData | Appends the supplied string to the existing string data.
cloneNode | Clones a new node.
deleteData | Deletes specified data.
hasChildNodes | Provides a fast way to determine whether a node has children.
insertBefore | Inserts a child node to the left of the specified node or at the end of the list.
insertData | Inserts a string at the specified offset.
removeChild | Removes the specified child node from the list of children and returns it.
replaceChild | Replaces the specified old child node with the supplied new child node.
replaceData | Replaces the specified number of characters with the supplied string.
selectNodes* | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
selectSingleNode* | Applies the specified pattern-matching operation to this node's context and returns the first matching node.
splitText | Splits this text node into two text nodes at the specified offset and inserts the new text node into the tree as a sibling that immediately follows this node.
substringData | Retrieves a substring of the full string from the specified range.
transformNode* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation.
transformNodeToObject | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation in the supplied object.

* denotes an extension to the W3C DOM.

Events

None.

See Also

IXMLDOMCDATASection | IXMLDOMText


IXMLDOMCharacterData

Provides text manipulation methods that are used by several objects.

[Script]

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeDescription;
xmlDoc.async = false;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.load("books.xml");
nodeDescription = xmlDoc.selectSingleNode("//description");
alert(nodeDescription.text);
[Visual Basic]

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeDescription As IXMLDOMElement
xmlDoc.async = False
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.Load "books.xml"
Set nodeDescription = xmlDoc.selectSingleNode("//description")
MsgBox nodeDescription.Text
[C/C++]

No C/C++ example available for this release.

Remarks

IXMLDOMCharacterData does not directly correspond to any node type. Methods are reused by IXMLDOMCDATASection, IXMLDOMComment, and IXMLDOMText. These methods handle large amounts of text, including sizes larger than can be manipulated natively using string constructs.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

IXMLDOMCDATASection | IXMLDOMCharacterData Members | IXMLDOMComment | IXMLDOMElement | IXMLDOMText


IXMLDOMCharacterData Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C+]

The following tables show the properties, methods, and events.

This interface inherits from IXMLDOMNode.

Properties

attributes | Contains the list of attributes for this node. Read-only.
baseName* | Returns the base name for the name qualified with the namespace. Read-only.
childNodes | Contains a node list containing the children nodes. Read-only.
data | Stores the node data depending on the node type. Read/write.
dataType* | Specifies the data type for this node. Read/write.
definition* | Returns the definition of the node in the document type definition (DTD) or schema. Read-only.
firstChild | Contains the first child of the node. Read-only.
lastChild | Returns the last child node. Read-only.
length | Specifies the length, in characters, of the data. Read-only.
namespaceURI* | Returns the Uniform Resource Identifier (URI) for the namespace. Read-only.
nextSibling | Contains the next sibling of the node in the parent's child list. Read-only.
nodeName | Contains the qualified name of the element, attribute, or entity reference, or a fixed string for other node types. Read-only.
nodeType | Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes. Read-only.
nodeTypedValue* | Contains the node value expressed in its defined data type. Read/write.
nodeTypeString* | Returns the node type in string form. Read-only.
nodeValue | Contains the text associated with the node. Read/write.
ownerDocument | Returns the root of the document that contains this node. Read-only.
parentNode | Contains the parent node. Read-only.
parsed* | Indicates the parsed status of the node and child nodes.
prefix* | Returns the namespace prefix. Read-only.
previousSibling | Contains the previous sibling of the node in the parent's child list. Read-only.
specified* | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the document type definition (DTD) or schema. Read-only.
text* | Contains the text content of the node or the concatenated text representing the node and its descendants. Read/write.
xml* | Contains the XML representation of the node and all its descendants. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) DOM.

Methods

appendChild | Appends a new child node as the last child of the node.
appendData | Appends the supplied string to the existing string data.
cloneNode | Clones a new node.
deleteData | Deletes the specified data.
hasChildNodes | Provides a fast way to determine whether a node has children.
insertBefore | Inserts a child node to the left of the specified node or at the end of the list.
insertData | Inserts a string at the specified offset.
removeChild | Removes the specified child node from the list of children and returns it.
replaceChild | Replaces the specified old child node with the supplied new child node.
replaceData | Replaces the specified number of characters with the supplied string.
selectNodes* | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
selectSingleNode* | Applies the specified pattern-matching operation to this node's context and returns the first matching node.
substringData | Retrieves a substring of the full string from the specified range.
transformNode* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation.
transformNodeToObject* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation in the supplied object.

* denotes an extension to the W3C DOM.

Events

None.

See Also

IXMLDOMCharacterData | IXMLDOMElement | IXMLDOMNode


IXMLDOMComment

Represents the content of an XML comment.

[Script]

Example

The following script example creates a new IXMLDOMComment (comment) and appends it as the last child node of DOMDocument.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var comment;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
comment = xmlDoc.createComment("Hello World!");
root.appendChild(comment);
alert(root.xml);
[Visual Basic]

Example

The following Microsoft® Visual Basic® example creates a new IXMLDOMComment (comment) and appends it as the last child node of DOMDocument.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim comment As IXMLDOMComment
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
Set comment = xmlDoc.createComment("Hello World!")
root.appendChild comment
MsgBox (root.xml)
[C/C++]

The following sample creates and appends a new XMLDOMComment node to the root document element.

#import "msxml4.dll"
using namespace MSXML2;

inline void TESTHR( HRESULT _hr )
   { if FAILED(_hr) throw(_hr); }

void XMLDOMCommentSample()
{
   try {
      IXMLDOMDocumentPtr docPtr;
      IXMLDOMNodePtr DOMNodePtr;

      //init
      TESTHR(CoInitialize(NULL));
      TESTHR(docPtr.CreateInstance("msxml2.domdocument"));

      // load a document
      _variant_t varXml("C:\\book.xml");
      _variant_t varOut((bool)TRUE);
      varOut = docPtr->load(varXml);
      if ((bool)varOut == FALSE)
         throw(0);
      MessageBox(NULL, _bstr_t(docPtr->xml), _T("Original Document"), MB_OK);

      DOMNodePtr = docPtr->createComment("This is a comment node");
      docPtr->documentElement->appendChild(DOMNodePtr);

      MessageBox(NULL, _bstr_t(docPtr->xml), _T("New Document"), MB_OK);

   } catch(...)
   {
      MessageBox(NULL, _T("Exception occurred"), _T("Error"), MB_OK);
   }
   CoUninitialize();
}

Remarks

The content refers to all characters between the start <!-- and end --> tags.

IXMLDOMComment has no unique members and exposes the same members IXMLDOMCharacterData.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

IXMLDOMCharacterData | IXMLDOMComment Members | IXMLDOMElement


IXMLDOMComment Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IXMLDOMCharacterData.

Properties

attributes | Contains the list of attributes for this node. Read-only.
baseName* | Returns the base name for the name qualified with the namespace. Read-only.
childNodes | Contains a node list containing the children nodes. Read-only.
data | Stores the node data depending on the node type. Read/write.
dataType* | Specifies the data type for this node. Read/write.
definition* | Returns the definition of the node in the document type definition (DTD) or schema. Read-only.
firstChild | Contains the first child of the node. Read-only.
lastChild | Returns the last child node. Read-only.
length | Specifies the length, in characters, of the data. Read-only.
namespaceURI* | Returns the Uniform Resource Identifier (URI) for the namespace. Read-only.
nextSibling | Contains the next sibling of this node in the parent's child list. Read-only.
nodeName | Contains the qualified name of the element, attribute, or entity reference, or a fixed string for other node types. Read-only.
nodeType | Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes. Read-only.
nodeTypedValue* | Contains this node's value expressed in its defined data type. Read/write.
nodeTypeString* | Returns the node type in string form. Read-only.
nodeValue | Contains the text associated with the node. Read/write.
ownerDocument | Returns the root of the document that contains the node. Read-only.
parentNode | Contains the parent node. Read-only.
parsed* | Indicates the parsed status of the node and child nodes.
prefix* | Returns the namespace prefix. Read-only.
previousSibling | Contains the previous sibling of the node in the parent's child list. Read-only.
specified* | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the DTD or schema. Read-only.
text* | Represents the text content of the node or the concatenated text representing the node and its descendants. Read/write.
xml* | Contains the XML representation of the node and all its descendants. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) DOM.

Methods

appendChild | Appends a new child node as the last child of the node.
appendData | Appends the supplied string to the existing string data.
cloneNode | Clones a new node.
deleteData | Deletes specified data.
hasChildNodes | Provides a fast way to determine whether a node has children.
insertBefore | Inserts a child node to the left of the specified node or at the end of the list.
insertData | Inserts the supplied string at the specified offset.
removeChild | Removes the specified child node from the list of children and returns it.
replaceChild | Replaces the specified old child node with the supplied new child node.
replaceData | Replaces the specified number of characters with the supplied string.
selectNodes* | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
selectSingleNode* | Applies the specified pattern-matching operation to this node's context and returns the first matching node.
substringData | Retrieves a substring of the full string from the specified range.
transformNode* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation.
transformNodeToObject* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation in the supplied object.

* denotes an extension to the W3C DOM.

Events

None.

See Also

IXMLDOMComment | IXMLDOMCharacterData


IXMLDOMDocument/DOMDocument

Represents the top level of the XML source. Includes members for retrieving and creating all other XML objects.

[Script]

Example

The following script examples demonstrate how to create the two types of objects.

var objDoc = new ActiveXObject("Msxml2.DOMDocument");
var objFTDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
[Visual Basic]

Example

The following Microsoft® Visual Basic® examples demonstrate how to create the two types of objects.

Dim objDoc As New Msxml2.DOMDocument
Dim objFTDoc As New Msxml2.FreeThreadedDOMDocument
[C/C++]

Example

The following C/C++ example creates DOMDocument and queries for the other interfaces.

HRESULT hr;
IXMLDOMDocument * pXMLDoc;
IXMLDOMNode * pXDN;
//...
hr = CoInitialize(NULL);
// Check the return value, hr...
hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
       IID_IXMLDOMDocument, (void**)&pXMLDoc);
// Check the return value, hr...
hr = pXMLDoc->QueryInterface(IID_IXMLDOMNode, (void **)&pXDN);
// Check the return value.

In addition to the DOM interfaces, DOMDocument implements a number of standard COM interfaces. You can call the QueryInterface method on DOMDocument to get the following interfaces.

Interface | Usage
IUnknown | DOMDocument is a wrapper object and each query for DOMDocument returns a new wrapper. You should only compare IUnknown interface pointers.
IConnectionPointContainer | Supports outgoing events ondataavailable and onreadystatechange through IPropertyNotifySink::OnChanged and IDispatch::Invoke.
IDispatch | Interface used by Visual Basic.
IDispatchEx | Interface used by dynamic late-bound scripting languages such as Microsoft Visual Basic Scripting Edition (VBScript) and Microsoft JScript®. This is not fully implemented. The following methods always return E_NOTIMPL: DeleteMemberByName or DeleteMemberByDispID, GetMemberProperties, GetMemberName, GetNextDispID, and GetNameSpaceParent.
IMarshal | Can be used to get a FreeThreadedMarshaler for a free-threaded DOM document. This allows the free-threaded DOM document to be used in Active Server Pages (ASP) shared Session and Application states for sharing XML documents across multiple clients in memory.
IObjectSafety | When the SetInterfaceSafetyOptions method is called with nonzero safety options, the Microsoft XML Parser (MSXML) will apply security rules before fetching XML data.
IObjectWithSite | Enables a host application to provide extra contextual information, such the base URL.
IOleCommandTarget | Used by a COM container to send an OLECMDID_STOP command to stop an asynchronous download.
IPersistMoniker | Provides control over how to bind the XML document to persistent data. Both synchronous and asynchronous loading are supported using BindToStorage on the given IMoniker. Save is not called; therefore the BindToStorage, IsDirty, and SaveCompleted methods return E_NOTIMPL.
IPersistStream | Used to save and load the XML document to and from an IStream.
IPersistStreamInit | Updated version of IPersistStream.
IProvideClassInfo | Provides an easy way to get ITypeInfo for the DOMDocument.
IStream | You can read and write directly to the document through the IStream that is returned. You cannot Seek during a Write operation, and the following methods are not implemented on this stream: SetSize, CopyTo, Commit, Revert, LockRegion, UnlockRegion, and Clone. This allows you to build an XML document efficiently by providing chunks of XML and calling Write on the stream. You can also use this to test the persistence of your current DOM document by calling "xmldoc1.save(xmldoc2)." The Save method uses this IStream interface.

When the object-creation methods (such as createElement) are used on the document, nodes are created in the context of the document (the ownerDocument property of the node points to the document), but the node is not part of the document tree. The node is only part of the document tree when it is explicitly added to the tree by calling insertBefore, replaceChild, or appendChild (or for attributes, setAttributeNode).

Remarks

DOMDocument represents the top node in the tree. It implements all of the base Document Object Model (DOM) document methods and provides additional members that support Extensible Stylesheet Language (XSL) and XML transformations.

Only one object can be created: the document. All other objects are accessed or created from the document.

The document can be created using either a free-threaded or a rental-threaded model. The behavior of the two models is identical; rental-threaded documents exhibit better performance because the parser does not need to manage concurrent access among threads. You cannot combine nodes or documents that are created using differing threading models. The document threading model is determined by the following settings.

Setting | Rental-threaded model | Free-threaded model
Version independent ProgID | Msxml2.DOMDocument | Msxml2.FreeThreadedDOMDocument
ProgID | Msxml2.DOMDocument.3.0 | Msxml2.FreeThreadedDOMDocument.3.0
ClassID | F6D90F11-9C73-11D3-B32E-00C04F990BB4 | F6D90F12-9C73-11D3-B32E-00C04F990BB4
VB Class Name | DOMDocument30 | FreeThreadedDOMDocument30

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

appendChild Method | createElement Method | DOMDocument Members | insertBefore Method | IXMLDOMNode | ownerDocument Property | replaceChild Method | setAttributeNode Method | XML DOM Persistence


IXMLDOMDocument/DOMDocument Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IXMLDOMNode.

Properties

async* | Specifies if asynchronous download is permitted. Read/write.
attributes | Contains the list of attributes for this node. Read-only.
baseName* | Returns the base name for the name qualified with the namespace. Read-only.
childNodes | Contains a node list containing the children nodes. Read-only.
dataType* | Specifies the data type for this node. Read/write.
definition* | Returns the definition of the node in the document type definition (DTD) or schema. Read-only.
doctype | Contains the document type node that specifies the DTD for this document. Read-only.
documentElement | Contains the root element of the document. Read/write.
firstChild | Contains the first child of this node. Read-only.
implementation | Contains the IXMLDOMImplementation object for the document. Read-only.
lastChild | Returns the last child node. Read-only.
namespaceURI* | Returns the Uniform Resource Identifier (URI) for the namespace. Read-only.
nextSibling | Contains the next sibling of the node in the parent's child list. Read-only.
nodeName | Returns the qualified name for attribute, document type, element, entity, or notation nodes. Returns a fixed string for all other node types. Read-only.
nodeType | Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes. Read-only.
nodeTypedValue* | Contains this node's value expressed in its defined data type. Read/write.
nodeTypeString* | Returns the node type in string form. Read-only.
nodeValue | Contains the text associated with the node. Read/write.
ondataavailable* | Specifies the event handler for the ondataavailable event. Read/write.
onreadystatechange* | Specifies the event handler to be called when the readyState property changes. Read/write.
ontransformnode* | Specifies the event handler for the ontransformnode event. Read/write.
ownerDocument | Returns the root of the document that contains this node. Read-only.
parentNode | Contains the parent node. Read-only.
parsed* | Indicates the parsed status of the node and child nodes. Read-only.
parseError* | Returns an IXMLDOMParseError object that contains information about the last parsing error. Read-only.
prefix* | Returns the namespace prefix. Read-only.
preserveWhiteSpace* | Specifies the default white space handling. Read/write.
previousSibling | Contains the previous sibling of the node in the parent's child list. Read-only.
readyState* | Indicates the current state of the XML document. Read-only.
resolveExternals* | Indicates whether external definitions (resolvable namespaces, DTD external subsets, and external entity references) are to be resolved at parse time, independent of validation. Read/write.
specified* | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the DTD or schema. Read-only.
text* | Represents the text content of the node or the concatenated text representing the node and its descendants. Read/write.
url* | Returns the URL for the last loaded XML document. Read-only.
validateOnParse* | Indicates whether the parser should validate this document. Read/write.
xml* | Contains the XML representation of the node and all its descendants. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) DOM.

Methods

abort* | Aborts an asynchronous download in progress.
appendChild | Appends a new child as the last child of this node.
cloneNode | Clones a new node.
createAttribute | Creates a new attribute with the specified name.
createCDATASection | Creates a CDATA section node that contains the supplied data.
createComment | Creates a comment node that contains the supplied data.
createDocumentFragment | Creates an empty IXMLDOMDocumentFragment object.
createElement | Creates an element node using the specified name.
createEntityReference | Creates a new EntityReference object.
createNode* | Creates a node using the supplied type, name, and namespace.
createProcessingInstruction | Creates a processing instruction node that contains the supplied target and data.
createTextNode | Creates a text node that contains the supplied data.
getElementsByTagName (DOMDocument) | Returns a collection of elements that have the specified name.
hasChildNodes | Provides a fast way to determine whether a node has children.
insertBefore | Inserts a child node to the left of the specified node or at the end of the list.
load* | Loads an XML document from the specified location.
loadXML* | Loads an XML document using the supplied string.
nodeFromID* | Returns the node that matches the ID attribute.
removeChild | Removes the specified child node from the list of children and returns it.
replaceChild | Replaces the specified old child node with the supplied new child node.
save* | Saves an XML document to the specified location.
selectNodes* | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
selectSingleNode* | Applies the specified pattern-matching operation to this node's context and returns the first matching node.
transformNode* | Processes this node and its children using the supplied XSLTransformations (XSLT) style sheet and returns the resulting transformation.
transformNodeToObject* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation in the supplied object.

* denotes an extension to the W3C DOM.

Events

ondataavailable* | Fires when new data is available.
onreadystatechange* | Fires when the readyState property changes.
ontransformnode* | Fires before the style sheet is applied to a node.l.

* denotes an extension to the W3C DOM.

See Also

IXMLDOMImplementation | IXMLDOMNode | IXMLDOMParseError | ondataavailable Event | ontransformnode Event | readyState Property


IXMLDOMDocument2

An extension of DOMDocument that supports schema caching and validation features, and switching on XML Path Language (XPath) support.

[Script]

Example

var objDoc = new ActiveXObject("Msxml2.DOMDocument");
var objFTDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
[Visual Basic]

Example

Dim objDoc As New Msxml2.DOMDocument
Dim objFTDoc As New Msxml2.FreeThreadedDOMDocument
[C/C++]

Example

The following C/C++ example creates DOMDocument and queries for the IXMLDOMDocument2 interface.

HRESULT hr;
IXMLDOMDocument2 * pXMLDoc = NULL;

//...
hr = CoInitialize(NULL); // Check the return value, hr...
hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
       IID_IXMLDOMDocument2, (void**)&pXMLDoc); // Check the return value, hr...

Remarks

The following CLSIDs support IID_XMLDOMDocument2 in CoCreateInstance. The following progIDs return an object that can be cast into an IXMLDOMDocument2 interface in Microsoft® Visual Basic®. IXMLDOMDocument2 methods and properties are transparently available in late-bound scripting languages that go through IDispatch.

The same is true for DOMDocument objects exposed through the responseXML (IXMLHTTPRequest) property, and the DOMDocument and XSLDocument properties in the XML Multipurpose Internet Mail Extension (MIME) Viewer.

CLSID | ProgID
CLSID_DOMDocument | Msxml2.DOMDocument
CLSID_DOMFreeThreadedDocument | Msxml2.FreeThreadedDOMDocument

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

Version-Independent ProgID: Msxml2.DOMDocument, Msxml2.FreeThreadedDOMDocument

Version-Independent CLSID: F6D90F11-9C73-11D3-B32E-00C04F990BB4, F6D90F12-9C73-11D3-B32E-00C04F990BB4 (free-threaded)

Version-Dependent ProgID: Msxml2.DOMDocument.3.0, Msxml2.FreeThreadedDOMDocument.3.0

Version-Dependent CLSID: f5078f32-c551-11d3-89b9-0000f81fe221, f5078f33-c551-11d3-89b9-0000f81fe221

See Also

IXMLDOMDocument2 Members | DOMDocument


IXMLDOMDocument2 Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from DOMDocument.

The methods and properties in this table are an extension to the Worldwide Web Consortium (W3C) DOM.

Properties

namespaces | Returns the list of namespaces in the document as XMLSchemaCache.
schemas | Finds schema documents during load.

Methods

getProperty (IXMLDOMDocument2) | Returns the default properties.
selectNodes | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
setProperty | Used for setting the SelectionLanguage, ServerHTTPRequest, or SelectionNamespaces internal properties (flags).
validate | Performs run-time validation on the currently loaded document using the currently loaded document type definition (DTD), schema, or schema collection.

Events

None.

See Also

IXMLDOMDocument2 | DOMDocument


IXMLDOMDocumentFragment

A lightweight object that is useful for tree insert operations.

[Script]

Example

var xmlDoc = new ActiveXObject("Msxml.DOMDocument");
var docFragment;
xmlDoc.async = false;
xmlDoc.loadXML("<root/>");
docFragment = xmlDoc.createDocumentFragment();
docFragment.appendChild(xmlDoc.createElement("node1"));
docFragment.appendChild(xmlDoc.createElement("node2"));
docFragment.appendChild(xmlDoc.createElement("node3"));
alert(docFragment.xml);
xmlDoc.documentElement.appendChild(docFragment);
alert(xmlDoc.xml);
[Visual Basic]

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim docFragment As IXMLDOMDocumentFragment
xmlDoc.async = False
xmlDoc.loadXML "<root/>"
Set docFragment = xmlDoc.createDocumentFragment()
docFragment.appendChild xmlDoc.createElement("node1")
docFragment.appendChild xmlDoc.createElement("node2")
docFragment.appendChild xmlDoc.createElement("node3")
MsgBox docFragment.xml
xmlDoc.documentElement.appendChild docFragment
MsgBox xmlDoc.xml
[C/C++]

Example

The following sample creates and appends a new IXMLDOMDocumentFragment to the root document element. It uses the following XML document.

<?xml version='1.0'?>
<COLLECTION
   xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
  <BOOK>
    <TITLE>Cosmos</TITLE>
    <AUTHOR>Carl Sagan</AUTHOR>
    <PUBLISHER>Ballantine Books</PUBLISHER>
  </BOOK>
  <BOOK>
    <TITLE>Catwings</TITLE>
    <AUTHOR>Ursula K. Le Guin</AUTHOR>
    <PUBLISHER>Scholastic</PUBLISHER>
  </BOOK>
  <BOOK>
    <TITLE>Home Town</TITLE>
    <AUTHOR>Tracy Kidder</AUTHOR>
    <PUBLISHER>Random House</PUBLISHER>
  </BOOK>
</COLLECTION>

#import "msxml4.dll"
using namespace MSXML2;

inline void TESTHR( HRESULT _hr )
   { if FAILED(_hr) throw(_hr); }

void XMLDOMDocumentFragmentSample()
{
   //HRESULT hr;
   try
   {
      IXMLDOMDocumentPtr docPtr;

      //init
      TESTHR(CoInitialize(NULL));
      TESTHR(docPtr.CreateInstance("msxml2.domdocument"));

      // load a document
      _variant_t varXml(_T("c:\\book.xml"));
      _variant_t varOut((bool)TRUE);
      varOut = docPtr->load(varXml);
      if ((bool)varOut == FALSE)
      {// show error description - IXMLDOMParseError sample
         IXMLDOMParseErrorPtr errPtr = docPtr->GetparseError();
         _bstr_t bstrErr(errPtr->reason);

         _tprintf(_T("Error:\n"));
         _tprintf(_T("Code = 0x%x\n"), errPtr->errorCode);
         _tprintf(_T("Source = Line : %ld; Char : %ld\n"), errPtr->line, errPtr->linepos);
         _tprintf(_T("Error Description = %s\n"), (char*)bstrErr);
      }
      else
      {// dom fragment sample

         // create a new node and add to the doc
         _variant_t varTyp((short)NODE_ELEMENT);
         _bstr_t varName(_T("BOOK"));
         IXMLDOMNodePtr nodePtr= docPtr->createNode(varTyp, varName, "");
         // create a doc fragment and associate the new node with it
         IXMLDOMDocumentFragmentPtr fragPtr = docPtr->createDocumentFragment();
         fragPtr->appendChild(nodePtr);
         // add some elements to the new node
         varName = _T("TITLE");
         IXMLDOMNodePtr nodePtr1= docPtr->createNode(varTyp, varName, "");
         nodePtr1->text = _T("A Suitable Boy");
         varName = "AUTHOR";
         IXMLDOMNodePtr nodePtr2= docPtr->createNode(varTyp, varName, "");
         nodePtr2->text = _T("Vikram Seth");
         nodePtr->appendChild(nodePtr1);
         nodePtr->appendChild(nodePtr2);
         // display the fragment contents
         MessageBox(NULL, fragPtr->xml, "", MB_OK);
         // add the fragment to the original doc
         docPtr->documentElement->appendChild(fragPtr);
         // display the modified doc contents
         MessageBox(NULL, docPtr->xml, "", MB_OK);
      }

   }
   catch (_com_error &e)
   {
      _tprintf(_T("Error:\n"));
      _tprintf(_T("Code = %08lx\n"), e.Error());
      _tprintf(_T("Code meaning = %s\n"), (char*) e.ErrorMessage());
      _tprintf(_T("Source = %s\n"), (char*) e.Source());
      _tprintf(_T("Error Description = %s\n"), (char*) e.Description());
   }
      catch(...)
   {
      _tprintf(_T("Unknown error!"));
   }
   CoUninitialize();
}

Remarks

The DocumentFragment object can represent a fragment of a document or portion of a document's tree. This makes it useful when implementing end user commands that allow users to rearrange a document, such as cutting and pasting.

The DocumentFragment node has special, defined behavior for IXMLDOMNode insert operations that makes it especially convenient for developers. When an IXMLDOMDocumentFragment is inserted into a DOMDocument node (or other node that can take children), the children of the DocumentFragment are inserted into the node rather than the DocumentFragment itself. This makes the DocumentFragment useful when the user wants to create nodes that are siblings; the DocumentFragment acts as the parent of these nodes so that the user can employ the standard methods from the IXMLDOMNode interface, such as insertBefore and appendChild.

The children of a DocumentFragment node make up zero or more nodes representing the tops of any subtrees defining the structure of the document. DocumentFragment nodes do not need to be well-formed XML documents (although they do need to follow the rules imposed upon well-formed XML parsed entities, which can have multiple top nodes). For example, a DocumentFragment might have only one child, and that child node could be a Text node. Such a structure model represents neither an HTML document nor a well-formed XML document.

IXMLDOMDocumentFragment has no unique members of its own, but exposes the same members as IXMLDOMNode.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

appendChild Method | insertBefore Method | IXMLDOMDocumentFragment Members | IXMLDOMNode | DOMDocument


IXMLDOMDocumentFragment Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IXMLDOMNode.

Properties

attributes | Contains the list of attributes for this node. Read-only.
baseName* | Returns the base name for the name qualified with the namespace. Read-only.
childNodes | Contains a node list containing the children nodes. Read-only.
dataType* | Specifies the data type for this node. Read/write.
definition* | Returns the definition of the node in the document type definition (DTD) or schema. Read-only.
firstChild | Contains the first child of the node. Read-only.
lastChild | Returns the last child node. Read-only.
namespaceURI* | Returns the Uniform Resource Identifier (URI) for the namespace. Read-only.
nextSibling | Contains the next sibling of the node in the parent's child list. Read-only.
nodeName | Contains the qualified name of the element, attribute, or entity reference, or a fixed string for other node types. Read-only.
nodeType | Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes. Read-only.
nodeTypedValue* | Contains thes node value expressed in its defined data type. Read/write.
nodeTypeString* | Returns the node type in string form. Read-only.
nodeValue | Contains the text associated with the node. Read/write.
ownerDocument | Returns the root of the document that contains the node. Read-only.
parentNode | Contains the parent node. Read-only.
parsed* | Indicates the parsed status of the node and child nodes. Read-only.
prefix* | Returns the namespace prefix. Read-only.
previousSibling | Contains the previous sibling of the node in the parent's child list. Read-only.
specified* | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the DTD or schema. Read-only.
text* | Represents the text content of the node or the concatenated text representing the node and its descendants. Read/write.
xml* | Contains the XML representation of the node and all its descendants. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) DOM.

Methods

appendChild | Appends a new child as the last child of the node.
cloneNode | Clones a new node.
hasChildNodes | Provides a fast way to determine whether a node has children.
insertBefore | Inserts a child node to the left of the specified node or at the end of the list.
removeChild | Removes the specified child node from the list of children and returns it.
replaceChild | Replaces the specified old child node with the supplied new child node.
selectNodes* | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
selectSingleNode* | Applies the specified pattern-matching operation to this node's context and returns the first matching node.
transformNode* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation.
transformNodeToObject* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation in the supplied object.

* denotes an extension to the W3C DOM.

Events

None.

See Also

IXMLDOMDocumentFragment | IXMLDOMNode


IXMLDOMDocumentType

Contains information associated with the document type declaration.

[Script]

No sample for this release.

[Visual Basic]

No sample for this release.

[C/C++]

Example

The following C/C++ example displays the doctype name of the document.

The following document was used.

<?xml version='1.0'?>
<!DOCTYPE COLLECTION [
<!ELEMENT COLLECTION    (DATE? , BOOK+) >
<!ATTLIST COLLECTION
    xmlns:dt CDATA #FIXED "urn:schemas-microsoft-com:datatypes">
<!ELEMENT BOOK         (TITLE, AUTHOR, PUBLISHER) >
<!ELEMENT DATE         (#PCDATA) >
<!ELEMENT TITLE         (#PCDATA)  >
<!ELEMENT AUTHOR        (#PCDATA)  >
<!ELEMENT PUBLISHER     (#PCDATA)  >
]>
<COLLECTION
   xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <BOOK>
    <TITLE>Cosmos</TITLE>
    <AUTHOR>Carl Sagan</AUTHOR>
    <PUBLISHER>Ballantine Books</PUBLISHER>
  </BOOK>
  <BOOK>
    <TITLE>Catwings</TITLE>
    <AUTHOR>Ursula K. Le Guin</AUTHOR>
    <PUBLISHER>Scholastic</PUBLISHER>
  </BOOK>
  <BOOK>
    <TITLE>Home Town</TITLE>
    <AUTHOR>Tracy Kidder</AUTHOR>
    <PUBLISHER>Random House</PUBLISHER>
  </BOOK>
</COLLECTION>

#import "msxml4.dll"
using namespace MSXML2;

inline void TESTHR( HRESULT _hr )
   { if FAILED(_hr) throw(_hr); }

void XMLDOMDocumentTypeSample()
{
   try
   {
      IXMLDOMDocumentPtr docPtr;

      //init
      TESTHR(CoInitialize(NULL));
      TESTHR(docPtr.CreateInstance(_T("msxml2.domdocument")));

      // load a document
      _variant_t varXml(_T("D:\\xmlSample\\xmlTest\\book1.xml"));
      _variant_t varOut((bool)TRUE);
      varOut = docPtr->load(varXml);
      if ((bool)varOut == FALSE)
      {// show error description - IXMLDOMParseError sample
         IXMLDOMParseErrorPtr errPtr = docPtr->GetparseError();
      // print error details
      }
      else
      {
         IXMLDOMDocumentTypePtr docTypPtr = docPtr->doctype;
         if (docTypPtr)
         {
            _bstr_t bstrTyp(docTypPtr->name);
            _tprintf(_T("Document type name = %s\n"), (TCHAR*)bstrTyp);
         }
            }
   }
   catch (_com_error &e)
   {
      _tprintf(_T("Error:\n"));
      _tprintf(_T("Code = %08lx\n"), e.Error());
      _tprintf(_T("Code meaning = %s\n"), (TCHAR*) e.ErrorMessage());
      _tprintf(_T("Source = %s\n"), (TCHAR*) e.Source());
      _tprintf(_T("Error Description = %s\n"), (TCHAR*) e.Description());
   }
      catch(...)
   {
      _tprintf(_T("Unknown error!"));
   }
   CoUninitialize();
}

Remarks

Each DOMDocument includes a doctype that identifies the document's IXMLDOMDocumentType. The IXMLDOMDocumentType provides access to the list of entities and notations defined for the document.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

doctype Property | DOMDocument | IXMLDOMDocumentType Members


IXMLDOMDocumentType Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IXMLDOMNode.

Properties

attributes | Contains the list of attributes for this node. Read-only.
baseName* | Returns the base name for the name qualified with the namespace. Read-only.
childNodes | Contains a node list containing the children nodes. Read-only.
dataType* | Specifies the data type for this node. Read/write.
definition* | Returns the definition of the node in the document type definition (DTD) or schema. Read-only.
entities | Contains a list of the entities declared in the DOCTYPE declaration. Read-only.
firstChild | Contains the first child of the node. Read-only.
lastChild | Returns the last child node. Read-only.
name | Contains the name of the document type. Read-only.
namespaceURI* | Returns the Uniform Resource Identifier (URI) for the namespace. Read-only.
nextSibling | Contains the next sibling of this node in the parent's child list. Read-only.
nodeName | Contains the qualified name of the element, attribute, or entity reference, or a fixed string for other node types. Read-only.
nodeType | Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes. Read-only.
nodeTypedValue* | Contains the node value expressed in its defined data type. Read/write.
nodeTypeString* | Returns the node type in string form. Read-only.
nodeValue | Contains the text associated with the node. Read/write.
notations | Contains a list of the IXMLDOMNotation objects present in the document type declaration. Read-only.
ownerDocument | Returns the root of the document that contains the node. Read-only.
parentNode | Contains the parent node. Read-only.
parsed* | Indicates the parsed status of the node and child nodes. Read-only.
prefix* | Returns the namespace prefix. Read-only.
previousSibling | Contains the previous sibling of the node in the parent's child list. Read-only.
specified* | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the document type definition (DTD) or schema. Read-only.
text* | Represents the text content of the node or the concatenated text representing the node and its descendants. Read/write.
xml* | Contains the XML representation of the node and all its descendants. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) DOM.

Methods

appendChild | Appends a new child as the last child of the node.
cloneNode | Clones a new node.
hasChildNodes | Provides a fast way to determine whether a node has children.
insertBefore | Inserts a child node to the left of the specified node or at the end of the list.
removeChild | Removes the specified child node from the list of children and returns it.
replaceChild | Replaces the specified old child node with the supplied new child node.
selectNodes* | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
selectSingleNode* | Applies the specified pattern-matching operation to this node's context and returns the first matching node.
transformNode* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation.
transformNodeToObject* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet, and returns the resulting transformation in the supplied object.

* denotes an extension to the W3C DOM.

Events

None.

See Also

IXMLDOMDocumentType | IXMLDOMNode | IXMLDOMNotation


IXMLDOMElement

Represents the element object.

[Script]

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var newRoot;
newRoot = xmlDoc.createElement("root");
xmlDoc.documentElement = newRoot;
alert(xmlDoc.xml);
[Visual Basic]

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim newRoot As IXMLDOMElement
Set newRoot = xmlDoc.createElement("root")
Set xmlDoc.documentElement = newRoot
MsgBox xmlDoc.xml
[C/C++]

Example

The following C/C++ example displays the entire XML document from its root element.

#import "msxml4.dll"
using namespace MSXML2;

inline void TESTHR( HRESULT _hr )
   { if FAILED(_hr) throw(_hr); }

void XMLDOMElementSample()
{
   try {
      IXMLDOMDocumentPtr docPtr;
      IXMLDOMElementPtr ElementPtr;

      //init
      TESTHR(CoInitialize(NULL));
      TESTHR(docPtr.CreateInstance("msxml2.domdocument"));

      // load a document
      _variant_t varXml("C:\\book.xml");
      _variant_t varOut((bool)TRUE);
      varOut = docPtr->load(varXml);
      if ((bool)varOut == FALSE)
         throw(0);
      ElementPtr = docPtr->documentElement;
      MessageBox(NULL, ElementPtr->xml, _T("Document from its root"), MB_OK);
   } catch(...)
   {
      MessageBox(NULL, _T("Exception occurred"), _T("Error"), MB_OK);
   }
   CoUninitialize();
}

Remarks

Element nodes are among the most common objects in the XML document tree. Element nodes can have attributes associated with them. By definition, attributes are not defined as child nodes of an element and are not considered to be part of the document tree. Accordingly, the IXMLDOMElement object provides methods to make it easier to manage attributes, including methods to associate an attribute with an element and to retrieve an attribute object and the attribute value by name.

To retrieve the set of all attributes associated with an element, you can also call the getAttribute method, which returns an IXMLDOMNamedNodeMap collection object that contains all the element's attributes.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

Version-Independent ProgID: Msxml2.DOMDocument

Version-Dependent ProgID: Msxml2.DOMDocument.3.0

See Also

getAttribute Method | IXMLDOMNamedNodeMap | IXMLDOMElement Members | IXMLDOMText | IXMLDOMNode


IXMLDOMElement Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IXMLDOMNode.

Properties

attributes | Contains the list of attributes for this node. Read-only.
baseName* | Returns the base name for the name qualified with the namespace. Read-only.
childNodes | Contains a node list containing the children nodes. Read-only.
dataType* | Specifies the data type for this node. Read/write.
definition* | Returns the definition of the node in the document type definition (DTD) or schema.
firstChild | Contains the first child of the node. Read-only.
lastChild | Returns the last child node. Read-only.
namespaceURI* | Returns the Uniform Resource Identifier (URI) for the namespace. Read-only.
nextSibling | Contains the next sibling of this node in the parent's child list. Read-only.
nodeName | Contains the qualified name of the element, attribute, or entity reference, or a fixed string for other node types. Read-only.
nodeType | Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes. Read-only.
nodeTypeString* | Returns the node type in string form. Read-only.
nodeValue | Contains the text associated with the node. Read/write.
ownerDocument | Returns the root of the document that contains the node. Read-only.
parentNode | Contains the parent node. Read-only.
parsed* | Indicates the parsed status of the node and child nodes. Read-only.
prefix* | Returns the namespace prefix. Read-only.
previousSibling | Contains the previous sibling of the node in the parent's child list. Read-only.
specified* | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the document type definition (DTD) or schema. Read-only.
tagName | Contains the element name. Read-only.
text* | Represents the text content of the node or the concatenated text representing the node and its descendants. Read/write.
xml* | Contains the XML representation of the node and all its descendants. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) DOM.

Methods

appendChild | Appends a new child as the last child of this node.
cloneNode | Clones a new node.
getAttribute | Gets the value of the attribute.
getAttributeNode | Gets the attribute node.
getElementsByTagName | Returns a list of all descendant elements that match the supplied name.
hasChildNodes | Provides a fast way to determine whether a node has children.
insertBefore | Inserts a child node to the left of the specified node or at the end of the list.
normalize | Normalizes all descendant elements by combining two or more adjacent text nodes into one unified text node.
removeAttribute | Removes or replaces the named attribute.
removeAttributeNode | Removes the specified attribute from this element.
removeChild | Removes the specified child node from the list of children and returns it.
replaceChild | Replaces the specified old child node with the supplied new child node.
selectNodes* | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
selectSingleNode* | Applies the specified pattern-matching operation to this node's context and returns the first matching node.
setAttribute | Sets the value of the named attribute.
setAttributeNode | Sets or updates the supplied attribute node on this element.
transformNode* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation.
transformNodeToObject* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation in the supplied object.

* denotes an extension to the W3C DOM.

Events

None.

See Also

IXMLDOMElement | IXMLDOMNode


IXMLDOMEntity

Represents a parsed or unparsed entity in the XML document.

[Script]

No sample for this release.

[Visual Basic]

No sample for this release.

[C/C++]

Example

BOOL DOMEntityNotationName()
{
   BOOL bResult = FALSE;
   IXMLDOMEntity *pIXMLDOMEntity = NULL;
   BSTR bstrName ;
   HRESULT hr;

   try
   {
      pIXMLDOMEntity = GetFirstEntity();

      if(pIXMLDOMEntity)
      {
         hr =   pIXMLDOMEntity->get_notationName(&bstrName);
         ::MessageBox(NULL, bstrName, _T("Notation name"), MB_OK);
         bResult = TRUE;
         ::SysFreeString(bstrName);
         pIXMLDOMEntity->Release();
      }
   }
   catch(...)
   {
      if(pIXMLDOMEntity)
         pIXMLDOMEntity->Release();
      DisplayErrorToUser();
   }
   return bResult;
}
IXMLDOMEntity* GetFirstEntity()
{
   IXMLDOMNamedNodeMap *pIXMLDOMNamedNodeMapEntities = NULL;
   IXMLDOMEntity *pIXMLDOMEntity = NULL;
   IXMLDOMNode *pIXMLDOMNode = NULL;
   IXMLDOMDocument *pIXMLDOMDocument = NULL;
   HRESULT hr;

   try
   {
      // Create an instance of DOMDocument and initialize
      // pIXMLDOMDocument.
      // Load/create an XML fragment.
      hr = pIXMLDOMDocument->get_doctype(&pIXMLDOMDocumentType);
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXMLDOMDocumentType)
      {
         hr = pIXMLDOMDocumentType->get_entities
            (&pIXMLDOMNamedNodeMapEntities);
         if(SUCCEEDED(hr) && pIXMLDOMNamedNodeMapEntities)
         {
            hr = pIXMLDOMNamedNodeMapEntities->nextNode(&pIXMLDOMNode);
            if(SUCCEEDED(hr) && pIXMLDOMNode)
            {
               hr = pIXMLDOMNode->QueryInterface(IID_IXMLDOMEntity,
                  (void**)&pIXMLDOMEntity );
               SUCCEEDED(m_hr) ? 0 : throw m_hr;
               pIXMLDOMNode->Release();
            }
            pIXMLDOMNamedNodeMapEntities->Release();
         }
         pIXMLDOMDocumentType->Release();
      }
   }
   catch(...)
   {
      if(pIXMLDOMNode)
         pIXMLDOMNode->Release();
      if(m_pIXMLDOMNamedNodeMapEntities)
         m_pIXMLDOMNamedNodeMapEntities->Release();
      if(m_pIXMLDOMDocumentType)
         m_pIXMLDOMDocumentType->Release();
      DisplayErrorToUser();
   }
   // Release pIXMLDOMEntity when finished using it.
   // Release pIXMLDOMDocument when finished using it.
   return pIXMLDOMEntity;
}

Remarks

IXMLDOMEntity represents the entity itself rather than the entity declaration. The Worldwide Web Consortium (W3C) Document Object Model (DOM) does not currently define an object that models the entity declaration.

According to the W3C DOM specification, an XML parser can completely expand entity references into entities before the structure model is passed to the DOM. When these entity references are expanded, the document tree does not contain any entity references.

When the Microsoft® XML Parser (MSXML) validates the XML document, it expands external entities (except binary entities). The nodes representing the expanded entity are available as read-only children of the entity reference. The Microsoft implementation does not expand these entities when it is not validating.

The nodeName property contains the name of the entity.

The structure of the entity child list is exactly the same as the structure of the child list for the IXMLDOMEntityReference object with the same nodeName value.

Level 1 of the W3C DOM application programming interface (API) does not define a way to change entity nodes. (All IXMLDOMEntity object properties are read-only.)

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

nodeName Property | IXMLDOMEntityReference | IXMLDOMEntity Members | DOMDocument


IXMLDOMEntity Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IXMLDOMNode.

Properties

attributes | Contains the list of attributes for this node. Read-only.
baseName* | Returns the base name for the name qualified with the namespace. Read-only.
childNodes | Contains a node list containing the children nodes. Read-only.
dataType* | Specifies the data type for this node. Read/write.
definition* | Returns the definition of the node in the document type definition (DTD) or schema. Read-only.
firstChild | Contains the first child of the node. Read-only.
lastChild | Returns the last child node. Read-only.
namespaceURI* | Returns the Uniform Resource Identifier (URI) for the namespace. Read-only.
nextSibling | Contains the next sibling of this node in the parent's child list. Read-only.
nodeName | Contains the qualified name of the element, attribute, or entity reference, or a fixed string for other node types. Read-only.
nodeType | Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes. Read-only.
nodeTypedValue* | Contains this node's value, expressed in its defined data type. Read/write.
nodeTypeString* | Returns the node type in string form. Read-only.
nodeValue | Contains the text associated with the node. Read/write.
notationName | Contains the notation name. Read-only.
ownerDocument | Returns the root of the document that contains the node. Read-only.
parentNode | Contains the parent node. Read-only.
parsed* | Indicates the parsed status of the node and child nodes. Read-only.
prefix* | Returns the namespace prefix. Read-only.
previousSibling | Contains the previous sibling of the node in the parent's child list. Read-only.
publicId | Contains the public identifier associated with the entity. Read-only.
specified* | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the DTD or schema. Read-only.
systemId | Contains the system identifier associated with the entity. Read-only.
text* | Contains the text content of the node or the concatenated text representing the node and its descendants.. Read/write.
xml* | Contains the XML representation of the node and all its descendants. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) DOM.

Methods

appendChild | Appends a new child node as the last child of the node.
cloneNode | Clones a new node.
hasChildNodes | Provides a fast way to determine whether a node has children.
insertBefore | Inserts a child node to the left of the specified node or at the end of the list.
removeChild | Removes the specified child node from the list of children and returns it.
replaceChild | Replaces the specified old child node with the supplied new child node.
selectNodes* | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
selectSingleNode* | Applies the specified pattern-matching operation to this node's context and returns the first matching node.
transformNode* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation.
transformNodeToObject* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation in the supplied object.

* denotes an extension to the W3C DOM.

Events

None.

See Also

IXMLDOMEntity | IXMLDOMNode


IXMLDOMEntityReference

Represents an entity reference node.

[C/C++]

IXMLDOMEntityReference has no unique properties or methods of its own, but exposes the same objects and properties as the IXMLDOMNode object.

[Script]

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root, nodeEntityReference;
xmlDoc.async = false;
xmlDoc.loadXML("<root/>");
nodeEntityReference = xmlDoc.createEntityReference("nbsp");
root = xmlDoc.documentElement;
root.appendChild(nodeEntityReference);
alert(xmlDoc.xml);
[Visual Basic]

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim nodeEntityReference As IXMLDOMEntityReference
xmlDoc.async = False
xmlDoc.loadXML "<root/>"
Set nodeEntityReference = xmlDoc.createEntityReference("nbsp")
Set root = xmlDoc.documentElement
root.appendChild nodeEntityReference
MsgBox xmlDoc.xml
[C/C++]

No C/C++ example for this release.

Remarks

If the XML parser expands entity references while building the structure model, no EntityReference objects appear in the tree.

XML does not require non-validating processors to handle external entity declarations (those made in the external subset or declared in external parameter entities). This means that parsed entities declared in the external subset need not be expanded, and therefore the replacement value of the entity might not be available. If available, the replacement value of the referenced entity appears in the child list of EntityReference.

The resolution of the children of the EntityReference (the replacement value of the referenced entity) can be evaluated. Actions such as calling the childNodes property are assumed to trigger the evaluation. Character entities are expanded by the XML parser and do not appear as entity references, but instead appear within the character text in Unicode.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

childNodes Property | IXMLDOMNode | IXMLDOMEntityReference Members | IXMLDOMEntity | DOMDocument


IXMLDOMEntityReference Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IXMLDOMNode interface.

Properties

attributes | Contains the list of attributes for this node. Read-only.
baseName* | Returns the base name for the name qualified with the namespace. Read-only.
childNodes | Contains a node list containing the children nodes. Read-only.
dataType* | Specifies the data type for this node. Read/write.
definition* | Returns the definition of the node in the document type definition (DTD) or schema. Read-only.
firstChild | Contains the first child of the node. Read-only.
lastChild | Returns the last child node. Read-only.
namespaceURI* | Returns the Uniform Resource Identifier (URI) for the namespace. Read-only.
nextSibling | Contains the next sibling of this node in the parent's child list. Read-only.
nodeName | Contains the qualified name of the element, attribute, or entity reference, or a fixed string for other node types. Read-only.
nodeType | Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes. Read-only.
nodeTypedValue* | Contains the node value expressed in its defined data type. Read/write.
nodeTypeString* | Returns the node type in string form. Read-only.
nodeValue | Contains the text associated with the node. Read/write.
ownerDocument | Returns the root of the document that contains the node. Read-only.
parentNode | Contains the parent node. Read-only.
parsed* | Indicates the parsed status of the node and child nodes. Read-only.
prefix* | Returns the namespace prefix. Read-only.
previousSibling | Contains the previous sibling of the node in the parent's child list. Read-only.
specified* | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the DTD or schema. Read-only.
text* | Represents the text content of the node or the concatenated text representing the node and its descendants. Read/write.
xml* | Contains the XML representation of the node and all its descendants. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) DOM.

Methods

appendChild | Appends a new child as the last child of this node.
cloneNode | Clones a new node.
hasChildNodes | Provides a fast way to determine whether a node has children.
insertBefore | Inserts a child node to the left of the specified node or at the end of the list.
removeChild | Removes the specified child node from the list of children and returns it.
replaceChild | Replaces the specified old child node with the supplied new child node.
selectNodes* | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
selectSingleNode* | Applies the specified pattern-matching operation to this node's context and returns the first matching node.
transformNode* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation.
transformNodeToObject* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation in the supplied object.

* denotes an extension to the W3C DOM.

Events

None.

See Also

IXMLDOMEntityReference | IXMLDOMNode


IXMLDOMImplementation

Provides methods that are independent of any particular instance of the Document Object Model (DOM).

[Script]

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var oImplementation;
xmlDoc.async = false;
xmlDoc.load("books.xml");
oImplementation = xmlDoc.implementation;
alert(oImplementation.hasFeature("DOM", "1.0"));
[Visual Basic]

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim oImplementation As IXMLDOMImplementation
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set oImplementation = xmlDoc.implementation
MsgBox oImplementation.hasFeature("DOM", "1.0")
[C/C++]

Example

IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
VARIANT_BOOL varbFlag ;
BSTR bstrOutput = NULL;
BSTR bstrFeature = ::SysAllocString(_T("MS-DOM"));
HRESULT hr;
IXMLDOMDocument *pIXMLDOMDocument = NULL;

try
{
   // Create an instance of DOMDocument and initialize pIXMLDOMDocument.
   // Load/create an XML fragment.
   hr = pIXMLDOMDocument->get_implementation(&pIXMLDOMImplementation);

   if(SUCCEEDED(hr) && pIXMLDOMImplementation)
   {
      hr = pIXMLDOMImplementation->hasFeature(bstrFeature, _T("1.0"), &varbFlag);
      if(varbFlag == VARIANT_TRUE )
         bstrOutput = ::SysAllocString(_T("Feature Supported"));
      else
         bstrOutput = ::SysAllocString(_T("Feature not Supported"));

      ::MessageBox(NULL, bstrOutput, bstrFeature, MB_OK);
      ::SysFreeString(bstrOutput);
      bstrOutput = NULL;
      ::SysFreeString(bstrFeature);
      bstrFeature = NULL;
      pIXMLDOMImplementation->Release();
   }
}
catch(...)
{
   if(bstrOutput)
      ::SysFreeString(bstrOutput);
   if(bstrFeature)
      ::SysFreeString(bstrFeature);
   if(pIXMLDOMImplementation)
      pIXMLDOMImplementation->Release();
   DisplayErrorToUser();
}
// Release pIXMLDOMDocument when finished using it.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

IXMLDOMImplementation Members | DOMDocument


IXMLDOMImplementation Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IDispatch.

Properties

None.

Methods

hasFeature Indicates support for the specified feature.

Events

None.

See Also

IXMLDOMImplementation


IXMLDOMNamedNodeMap

Adds support for namespaces and iteration through the collection of attribute nodes.

[Script]

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeBook, namedNodeMap;
xmlDoc.async = false;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.load("books.xml");
nodeBook = xmlDoc.selectSingleNode("//book");
namedNodeMap = nodeBook.attributes;
alert(namedNodeMap.length);
[Visual Basic]

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeBook As IXMLDOMNode
Dim namedNodeMap As IXMLDOMNamedNodeMap
xmlDoc.async = False
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.Load "books.xml"
Set nodeBook = xmlDoc.selectSingleNode("//book")
Set namedNodeMap = nodeBook.Attributes
MsgBox namedNodeMap.length
[C/C++]

Example

The following C/C++ example creates and appends a new attribute to the root document element.

#import "msxml4.dll"
using namespace MSXML2;

inline void TESTHR( HRESULT _hr )
   { if FAILED(_hr) throw(_hr); }

void XMLDOMNamedNodeMap()
{
   try {
      IXMLDOMDocumentPtr docPtr;
      IXMLDOMNodePtr DOMNodePtr;
      IXMLDOMNamedNodeMapPtr DOMNamedNodeMapPtr;

      //init
      TESTHR(CoInitialize(NULL));
      TESTHR(docPtr.CreateInstance("msxml2.domdocument"));

      VARIANT vtTemp;

      vtTemp.vt=VT_I2;
      vtTemp.iVal = MSXML2::NODE_ATTRIBUTE;

      // load a document
      _variant_t varXml("C:\\book.xml");
      _variant_t varOut((bool)TRUE);
      varOut = docPtr->load(varXml);
      if ((bool)varOut == FALSE)
         throw(0);

      DOMNodePtr = docPtr->createNode(vtTemp, "Sci-Fi", "");
      DOMNamedNodeMapPtr = docPtr->documentElement->attributes;
      DOMNamedNodeMapPtr->setNamedItem(DOMNodePtr);

      MessageBox(NULL, _bstr_t(docPtr->xml), _T("New Document"), MB_OK);

   } catch(...)
   {
      MessageBox(NULL, _T("Exception occurred"), _T("Error"), MB_OK);
   }
   CoUninitialize();
}

Remarks

IXMLDOMNamedNodeMap is a node collection that allows access by name as well as by index. This collection is typically used for attributes.

The World Wide Web Consortium (W3C) Document Object Model (DOM) definition does not require NamedNodeMap objects to be maintained in any particular order. Objects contained in a NamedNodeMap can also be accessed by an ordinal index, but this is simply to allow convenient enumeration and does not imply that the DOM specifies an order for these nodes. DOM implementations are not required to preserve the node order.

The Microsoft® implementation preserves the attributes in the order in which they appear in the source. Additional attributes are added to the end of the list. A namespace attribute (xmlns) is inserted as the first in the list if the tag name requires the namespace, or immediately before the attribute that uses an undeclared namespace.

Like the node list, however, a named node map collection is live; that is, the addition and removal of nodes, and changes within nodes, are immediately reflected in the collection. This means that two successive requests for items using the same index can return two different items, depending on changes to the collection. This also means that changes to the node objects are immediately available in the nodes obtained from the list.

When a default value is specified in the schema for an attribute and that attribute is removed, it is automatically regenerated with the default value, as specified in the W3C standard. The attribute reappears immediately because the collection is live, with a corresponding change to the count of items in the collection. When removing an attribute with such a default setting, you must again retrieve the number of items in the collection to obtain an accurate count. You should also reset any index into the collection.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

Version-Independent ProgID: Msxml2.DOMDocument, Msxml2.FreeThreadedDOMDocument

Version-Dependent ProgID: Msxml2.DOMDocument.3.0, Msxml2.FreeThreadedDOMDocument.3.0

See Also

IXMLDOMNamedNodeMap Members | IXMLDOMNode


IXMLDOMNamedNodeMap Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IDispatch.

Properties

length Indicates the number of items in the collection. Read-only.

Methods

getNamedItem | Retrieves the attribute with the specified name.
getQualifiedItem* | Returns the attribute with the specified namespace and attribute name.
item | Allows random access to individual nodes within the collection. Read-only.
removeNamedItem | Removes an attribute from the collection.
removeQualifiedItem | Removes the attribute with the specified namespace and attribute name.
reset (IXMLDOMNamedNodeMap) | Resets the iterator.
setNamedItem | Adds the supplied node to the collection.

* denotes an extension to the World Wide Web Consortium (W3C) Document Object Model (DOM).

Events

None.

See Also

IXMLDOMNamedNodeMap


IXMLDOMNode

Extends the core node with support for data types, namespaces, document type definitions (DTDs), and schemas.

[Script]

Example

The following script example creates IXMLDOMNode, currNode, and displays its XML.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var currNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
currNode = xmlDoc.documentElement.childNodes.item(1);
alert(currNode.xml);
[Visual Basic]

Example

The following Microsoft® Visual Basic® example creates IXMLDOMNode, currNode, and displays its XML.

Dim xmlDoc As New Msxml2.DOMDocument
Dim currNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set currNode = xmlDoc.documentElement.childNodes.Item(1)
MsgBox currNode.xml
[C/C++]

Example

The following C/C++ example creates and appends a new node to the document root.

#import "msxml4.dll"
using namespace MSXML2;

inline void TESTHR( HRESULT _hr )
   { if FAILED(_hr) throw(_hr); }

void XMLDOMNodeSample()
{
   try {
      IXMLDOMDocumentPtr docPtr;
      IXMLDOMNodePtr DOMNodePtr;

      //init
      TESTHR(CoInitialize(NULL));
      TESTHR(docPtr.CreateInstance("msxml2.domdocument"));

      VARIANT vtTemp;

      vtTemp.vt=VT_I2;
      vtTemp.iVal = NODE_ELEMENT;

      // load a document
      _variant_t varXml("C:\\book.xml");
      _variant_t varOut((bool)TRUE);
      varOut = docPtr->load(varXml);
      if ((bool)varOut == FALSE)
         throw(0);
      MessageBox(NULL, _bstr_t(docPtr->xml), _T("Original Document"), MB_OK);
      DOMNodePtr = docPtr->createNode(vtTemp, "VIDEOS", "");
      docPtr->documentElement->appendChild(DOMNodePtr);
      MessageBox(NULL, _bstr_t(docPtr->xml), _T("New Document"), MB_OK);

   } catch(...)
   {
      MessageBox(NULL, _T("Exception occurred"), _T("Error"), MB_OK);
   }
   CoUninitialize();
}

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

IXMLDOMNode Members | IXMLDOMNodeList


IXMLDOMNode Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IDispatch.

Properties

attributes | Contains the list of attributes for this node. Read-only.
baseName* | Returns the base name for the name qualified with the namespace. Read-only.
childNodes | Contains a node list containing the children nodes. Read-only.
dataType* | Specifies the data type for this node. Read/write.
definition* | Returns the definition of the node in the document type definition (DTD) or schema. Read-only.
firstChild | Contains the first child of this node. Read-only.
lastChild | Returns the last child node. Read-only.
namespaceURI* | Returns the Uniform Resource Identifier (URI) for the namespace. Read-only.
nextSibling | Contains the next sibling of this node in the parent's child list. Read-only.
nodeName | Returns the qualified name for attribute, document type, element, entity, or notation nodes. Returns a fixed string for all other node types.
nodeType | Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes. Read-only.
nodeTypedValue* | Contains the node value expressed in its defined data type. Read/write.
nodeTypeString* | Returns the node type in string form. Read-only.
nodeValue | Contains the text associated with the node. Read/write.
ownerDocument | Returns the root of the document that contains the node. Read-only.
parentNode | Contains the parent node. Read-only.
parsed* | Indicates the parsed status of the node and child nodes. Read-only.
prefix* | Returns the namespace prefix. Read-only.
previousSibling | Contains the previous sibling of the node in the parent's child list. Read-only.
specified* | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the DTD or schema. Read-only.
text* | Represents the text content of the node or the concatenated text representing the node and its descendants. Read/write.
xml* | Contains the XML representation of the node and all its descendants. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) DOM.

Methods

appendChild | Appends a new child as the last child of the node.
cloneNode | Clones a new node.
hasChildNodes | Provides a fast way to determine whether a node has children.
insertBefore | Inserts a child node to the left of the specified node or at the end of the list.
removeChild | Removes the specified child node from the list of children and returns it.
replaceChild | Replaces the specified old child node with the supplied new child node.
selectNodes* | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
selectSingleNode* | Applies the specified pattern-matching operation to this node's context and returns the first matching node.
transformNode* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation.
transformNodeToObject* | Processes this node and its children using the supplied XSLT style sheet and returns the resulting transformation in the supplied object.

* denotes an extension to the W3C DOM.

Events

None.

See Also

IXMLDOMNode


IXMLDOMNodeList

Supports iteration through the live collection, in addition to indexed access.

[Script]

Example

The following script example creates an IXMLDOMNodeList object by using the document's getElementsByTagName method.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var objNodeList;
xmlDoc.load("books.xml");
objNodeList = xmlDoc.getElementsByTagName("author");
alert(objNodeList.length);
[Visual Basic]

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNodeList object by using the document's getElementsByTagName method.

Dim xmlDoc As New Msxml2.DOMDocument
Dim objNodeList As IXMLDOMNodeList
xmlDoc.Load ("books.xml")
Set objNodeList = xmlDoc.getElementsByTagName("author")
MsgBox objNodeList.length
[C/C++]

Example

The following C/C++ example gets all elements with node name "AUTHOR" and displays the number of nodes found with the following sample.

<?xml version='1.0'?>
<COLLECTION
   xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
  <BOOK>
    <TITLE>Cosmos</TITLE>
    <AUTHOR>Carl Sagan</AUTHOR>
    <PUBLISHER>Ballantine Books</PUBLISHER>
  </BOOK>
  <BOOK>
    <TITLE>Catwings</TITLE>
    <AUTHOR>Ursula K. Le Guin</AUTHOR>
    <PUBLISHER>Scholastic</PUBLISHER>
  </BOOK>
  <BOOK>
    <TITLE>Home Town</TITLE>
    <AUTHOR>Tracy Kidder</AUTHOR>
    <PUBLISHER>Random House</PUBLISHER>
  </BOOK>
</COLLECTION>

#import "msxml4.dll"
using namespace MSXML2;

inline void TESTHR( HRESULT _hr )
   { if FAILED(_hr) throw(_hr); }

void XMLDOMNodeListSample()
{
   try {
      IXMLDOMDocumentPtr docPtr;
      IXMLDOMNodeListPtr NodeListPtr;
      IXMLDOMNodePtr DOMNodePtr;

      //init
      TESTHR(CoInitialize(NULL));
      TESTHR(docPtr.CreateInstance("msxml2.domdocument"));

      // load a document
      _variant_t varXml("C:\\book.xml");
      _variant_t varOut((bool)TRUE);
      varOut = docPtr->load(varXml);
      if ((bool)varOut == FALSE)
         throw(0);
      NodeListPtr = docPtr->getElementsByTagName("AUTHOR");
      MessageBox(NULL, _bstr_t(NodeListPtr->length), _T("Node List length"), MB_OK);
   } catch(...)
   {
      MessageBox(NULL, _T("Exception occurred"), _T("Error"), MB_OK);
   }
   CoUninitialize();
}

Remarks

A NodeList collection is live; that is, the addition and removal of nodes, and changes within nodes, are immediately reflected in the collection. This means that two successive requests for items using the same index can return two different items, depending on changes to the collection. This also means that changes to the node objects are immediately available in the nodes obtained from the list. The collection can also be accessed using the "for...next" construct.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

IXMLDOMNodeList Members | IXMLDOMNode


IXMLDOMNodeList Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IDispatch.

Properties

length Indicates the number of items in the collection. Read-only.

Methods

item | Allows random access to individual nodes within the collection.
nextNode* | Returns the next node in the collection.
reset* | Resets the iterator.

* denotes an extension to the Worldwide Web Consortium (W3C) Document Object Model (DOM).

Events

None.

See Also

IXMLDOMNodeList


IXMLDOMNotation

Contains a notation declared in the document type definition (DTD) or schema.

[Script]

No sample for this release.

[Visual Basic]

No sample for this release.

[C/C++]

The following C/C++ example displays the names of the notation nodes in the DTD declaration of the document.

The following document was used.

<?xml version='1.0'?>
<!DOCTYPE COLLECTION [
<!NOTATION XLS PUBLIC "http://www.microsoft.com/office/excel/">
<!ELEMENT COLLECTION    (DATE? , BOOK+) >
<!ATTLIST COLLECTION
    xmlns:dt CDATA #FIXED "urn:schemas-microsoft-com:datatypes">
<!ELEMENT BOOK(TITLE, AUTHOR, PUBLISHER) >
<!ELEMENT DATE(#PCDATA) >
<!ELEMENT TITLE         (#PCDATA)  >
<!ELEMENT AUTHOR        (#PCDATA)  >
<!ELEMENT PUBLISHER     (#PCDATA)  >
]>
<COLLECTION
   xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <BOOK>
    <TITLE>Cosmos</TITLE>
    <AUTHOR>Carl Sagan</AUTHOR>
    <PUBLISHER>Ballantine Books</PUBLISHER>
  </BOOK>
  <BOOK>
    <TITLE>Catwings</TITLE>
    <AUTHOR>Ursula K. Le Guin</AUTHOR>
    <PUBLISHER>Scholastic</PUBLISHER>
  </BOOK>
  <BOOK>
    <TITLE>Home Town</TITLE>
    <AUTHOR>Tracy Kidder</AUTHOR>
    <PUBLISHER>Random House</PUBLISHER>
  </BOOK>
</COLLECTION>

#import "msxml4.dll"
using namespace MSXML2;

inline void TESTHR( HRESULT _hr )
   { if FAILED(_hr) throw(_hr); }

void XMLDOMNotationSample()
{
   try
   {
      IXMLDOMDocumentPtr docPtr;

      //init
      TESTHR(CoInitialize(NULL));
      TESTHR(docPtr.CreateInstance(_T("msxml2.domdocument")));

      // load a document
      _variant_t varXml(("D:\\xmlSample\\xmlTest\\book1.xml"));
      _variant_t varOut((bool)TRUE);
      varOut = docPtr->load(varXml);
      if ((bool)varOut == FALSE)
      {// show error description - IXMLDOMParseError sample
         IXMLDOMParseErrorPtr errPtr = docPtr->GetparseError();

      // display eror information
      }
      else
      {
         IXMLDOMDocumentTypePtr docTypPtr = docPtr->doctype;
         if (docTypPtr)
         {
            int nCounter;
            IXMLDOMNamedNodeMapPtr XMLDOMNamedNodeMapPtr =
docTypPtr->Getnotations();

            for(nCounter=0;nCounter < XMLDOMNamedNodeMapPtr->length; nCounter ++)
            {
               IXMLDOMNotationPtr XMLDOMNotationPtr =
XMLDOMNamedNodeMapPtr->Getitem(nCounter);

               _tprintf(_T("%s"), (TCHAR*)XMLDOMNotationPtr->nodeName);
            }
         }
      }

   }
   catch (_com_error &e)
   {
      _tprintf(_T("Error:\n"));
      _tprintf(_T("Code = %08lx\n"), e.Error());
      _tprintf(_T("Code meaning = %s\n"), (TCHAR*) e.ErrorMessage());
      _tprintf(_T("Source = %s\n"), (TCHAR*) e.Source());
      _tprintf(_T("Error Description = %s\n"), (TCHAR*) e.Description());
   }
      catch(...)
   {
      _tprintf(_T("Unknown error!"));
   }
   CoUninitialize();
}

Remarks

Notations identify by name the format of unparsed entities, the format of elements that bear a notation attribute, or the application to which a processing instruction is addressed.

The nodeName property contains the notation name.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

nodeName Property | IXMLDOMNode | IXMLDOMNotation Members


IXMLDOMNotation Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IXMLDOMNode.

Properties

attributes | Contains the list of attributes for this node. Read-only.
baseName* | Returns the base name for the name qualified with the namespace. Read-only.
childNodes | Contains a node list containing the children nodes. Read-only.
dataType* | Specifies the data type for this node. Read/write.
definition* | Returns the definition of the node in the document type definition (DTD) or schema. Read-only.
firstChild | Contains the first child of the node. Read-only.
lastChild | Returns the last child node. Read-only.
namespaceURI (IXMLDOMNode)* | Returns the Uniform Resource Identifier (URI) for the namespace. Read-only.
nextSibling | Contains the next sibling of this node in the parent's child list. Read-only.
nodeName | Contains the qualified name of the element, attribute, or entity reference, or a fixed string for other node types. Read-only.
nodeType | Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes. Read-only.
nodeTypedValue* | Contains the node value expressed in its defined data type. Read/write.
nodeTypeString* | Returns the node type in string form. Read-only.
nodeValue | Contains the text associated with the node. Read/write.
ownerDocument | Returns the root of the document that contains the node. Read-only.
parentNode | Contains the parent node. Read-only.
parsed* | Indicates the parsed status of the node and child nodes. Read-only.
prefix* | Returns the namespace prefix. Read-only.
previousSibling | Contains the previous sibling of the node in the parent's child list. Read-only.
publicId (IXMLDOMNotation) | Contains the public identifier for the notation. Read-only.
specified* | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the DTD or schema. Read-only.
systemId (IXMLDOMNotation) | Contains the system identifier for the notation. Read-only.
text* | Represents the text content of the node or the concatenated text representing the node and its descendants.
xml* | Contains the XML representation of the node and all its descendants. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) DOM.

Methods

appendChild | Appends a new child as the last child of this node.
cloneNode | Clones a new node.
hasChildNodes | Provides a fast way to determine whether a node has children.
insertBefore | Inserts a child node to the left of the specified node or at the end of the list.
removeChild | Removes the specified child node from the list of children and returns it.
replaceChild | Replaces the specified old child node with the supplied new child node.
selectNodes* | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
selectSingleNode* | Applies the specified pattern-matching operation to this node's context and returns the first matching node.
transformNode* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation.
transformNodeToObject* | Processes this node and its children using the supplied XSLT style sheet and returns the resulting transformation.

* denotes an extension to the W3C DOM.

Events

None.

See Also

IXMLDOMNode | IXMLDOMNotation


IXMLDOMParseError

Returns detailed information about the last parse error, including the error number, line number, character position, and a text description.

[Script]

Example

The following script example attempts to load an XML document. It then tests the errorCode property of the IXMLDOMParseError object to see if an error has occurred.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
if (xmlDoc.parseError.errorCode != 0) {
  alert("A parse error occurred.");
} else {
  alert(xmlDoc.documentElement.xml);
}
[Visual Basic]

Example

The following Microsoft® Visual Basic® example attempts to load an XML document. It then tests the errorCode property of the IXMLDOMParseError object to see if an error has occurred.

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.async = False
xmlDoc.Load ("books.xml")
If xmlDoc.parseError.errorCode <> 0 Then
  MsgBox "A parse error occurred."
Else
  MsgBox xmlDoc.documentElement.xml
End If
[C/C++]

Example

The following C/C++ example reads a document with a missing end "TITLE" tag (in the second book) and displays the error.

#import "msxml4.dll"
using namespace MSXML2;

inline void TESTHR( HRESULT _hr )
   { if FAILED(_hr) _com_issue_error(_hr); }

void XMLDOMParserSample()
{
   try
   {
      IXMLDOMDocumentPtr docPtr;

      //init
      TESTHR(CoInitialize(NULL));
      TESTHR(docPtr.CreateInstance("msxml2.domdocument"));

      // load a document
      _variant_t varXml("D:\\xmlSample\\xmlTest\\book.xml");
      _variant_t varOut((bool)TRUE);
      varOut = docPtr->load(varXml);
      if ((bool)varOut == FALSE)
      {
         IXMLDOMParseErrorPtr errPtr = docPtr->GetparseError();
         _bstr_t bstrErr(errPtr->reason);

         printf("Error:\n");
         printf("Code = 0x%x\n", errPtr->errorCode);
         printf("Source = Line : %ld; Char : %ld\n", errPtr->line, errPtr->linepos);
         printf("Error Description = %s\n", (char*)bstrErr);

      }
      else
      {
         printf("Load successful");
      }

   }
   catch (_com_error &e)
   {
      printf("Error:\n");
      printf("Code = %08lx\n", e.Error());
      printf("Code meaning = %s\n", (char*) e.ErrorMessage());
      printf("Source = %s\n", (char*) e.Source());
      printf("Error Description = %s\n", (char*) e.Description());
   }
      catch(...)
   {
      printf("Unknown error!");
   }
   CoUninitialize();
}

Document

<?xml version='1.0'?>
<COLLECTION
   xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
  <BOOK>
    <TITLE>Cosmos</TITLE>
    <AUTHOR>Carl Sagan</AUTHOR>
    <PUBLISHER>Ballantine Books</PUBLISHER>
  </BOOK>
  <BOOK>
    <TITLE>Catwings
    <AUTHOR>Ursula K. Le Guin</AUTHOR>
    <PUBLISHER>Scholastic</PUBLISHER>
  </BOOK>
  <BOOK>
    <TITLE>Home Town</TITLE>
    <AUTHOR>Tracy Kidder</AUTHOR>
    <PUBLISHER>Random House</PUBLISHER>
  </BOOK>
</COLLECTION>

Output

Error:
Code = 0xc00ce56d
Source = Line : 14; Char : 5
Error Description = End tag 'BOOK' does not match the start tag 'TITLE'.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

IXMLDOMParseError Members


IXMLDOMParseError Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IDispatch.

Properties

errorCode | Contains the error code of the last parse error. Read-only.
filepos | Contains the absolute file position where the error occurred. Read-only.
line | Specifies the line number that contains the error. Read-only.
linepos | Contains the character position within the line where the error occurred. Read-only.
reason | Describes the reason for the error. Read-only.
srcText | Returns the full text of the line containing the error. Read-only.
url | Contains the URL of the XML document containing the last error. Read-only.

Methods

None.

Events

None.

See Also

IXMLDOMParseError


IXMLDOMProcessingInstruction

Represents a processing instruction, which XML defines to keep processor-specific information in the text of the document.

[Script]

Example

The following script example creates a new IXMLDOMProcessingInstruction object and displays its XML representation.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var pi;
pi = xmlDoc.createProcessingInstruction("xml", "version=\"1.0\"");
alert(pi.xml);

Output (in a message box)

<?xml version="1.0"?>
[Visual Basic]

Example

The following Microsoft® Visual Basic® example creates a new IXMLDOMProcessingInstruction object and displays its XML representation.

Dim xmlDoc As New Msxml2.DOMDocument
Dim pi As IXMLDOMProcessingInstruction
Set pi = xmlDoc.createProcessingInstruction("xml", "version=""1.0""")
MsgBox pi.xml

Output (in a message box)

<?xml version="1.0"?>
[C/C++]

Example

#import "msxml4.dll"
using namespace MSXML2;

#define CHECK_AND_RELEASE(pInterface)  \
   if(pInterface) \
   {\
      pInterface->Release();\
      pInterface = NULL;\
   }\

#define RELEASE(pInterface)  \
   {\
      pInterface->Release();\
      pInterface = NULL;\
   }\

BOOL BuildDynamicXMLwithProcessingInstruction()
{
   BOOL bResult = FALSE;
   IXMLDOMDocument *pIXMLDOMDocument=NULL;
   IXMLDOMElement *pIXMLDOMElement=NULL;
   IXMLDOMProcessingInstruction *pIXMLDOMProcessingInstruction=NULL;
   IXMLDOMNode *pIXMLDOMNode = NULL;
   HRESULT hr ;
   BSTR bstrValue ;

   try
   {
      hr=CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_SERVER,
IID_IXMLDOMDocument2, (LPVOID*)(&pIXMLDOMDocument));
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXMLDOMDocument)
      {
               hr=pIXMLDOMDocument->createElement(CComBSTR(L"Node1"), &pIXMLDOMElement);
         if(SUCCEEDED(hr) && pIXMLDOMElement)
         {
            hr=pIXMLDOMElement->put_text(_T("test"));
            if(SUCCEEDED(hr))
            {
               hr=pIXMLDOMDocument->createProcessingInstruction(_T("xml"),
 _T("version='1.0'"), &pIXMLDOMProcessingInstruction);
               if(SUCCEEDED(hr) && pIXMLDOMProcessingInstruction)
               {
                  pIXMLDOMDocument->appendChild(
                              pIXMLDOMProcessingInstruction, &pIXMLDOMNode);
               pIXMLDOMDocument->putref_documentElement(pIXMLDOMElement);
               hr=pIXMLDOMDocument->get_xml(&bstrValue);
               if(SUCCEEDED(hr))
               {

            ::MessageBox(NULL,bstrValue,L"Loaded Doc",MB_OK);
                  bResult=TRUE;
                  }
                  CHECK_AND_RELEASE(pIXMLDOMNode);
                  RELEASE(pIXMLDOMProcessingInstruction);
               }
            }
            RELEASE(pIXMLDOMElement);
         }
         RELEASE(pIXMLDOMDocument);
      }
   }
   catch(...)
   {
      CHECK_AND_RELEASE(pIXMLDOMElement);
      CHECK_AND_RELEASE(pIXMLDOMDocument);
      CHECK_AND_RELEASE(pIXMLDOMNode);
      CHECK_AND_RELEASE(pIXMLDOMProcessingInstruction);
      DisplayErrorToUser();
   }
   return bResult;
}

Output (in a message box)

<?xml version="1.0"?>
<Node1>test</Node1>

Remarks

The content of the ProcessingInstruction node is the entire content between the delimiters of the processing instruction.

The content of this node is usually subdivided into the target (the application to which this processing instruction is directed) and the content of the processing instruction. The target consists of the first token following the start of the tag, while the content of the processing instruction refers to the text that extends from the first non-white space character after the target through the character immediately preceding the ?>, which signifies the end of the tag.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

DOMDocument | IXMLDOMProcessingInstruction Members


IXMLDOMProcessingInstruction Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IXMLDOMNode.

Properties

attributes | Contains the list of attributes for this node. Read-only.
baseName* | Returns the base name for the name qualified with the namespace. Read-only.
childNodes | Contains a node list containing the children nodes. Read-only.
data (IXMLDOMProcessingInstruction) | Retrieves and sets the content of the processing instruction, excluding the target. Read/write.
dataType* | Specifies the data type for this node. Read/write.
definition* | Returns the definition of the node in the document type definition (DTD) or schema. Read-only.
firstChild | Contains the first child of the node. Read-only.
lastChild | Returns the last child node. Read-only.
namespaceURI* | Returns the Uniform Resource Identifier (URI) for the namespace. Read-only.
nextSibling | Contains the next sibling of the node in the parent's child list. Read-only.
nodeName | Contains the qualified name of the element, attribute, or entity reference, or a fixed string for other node types. Read-only.
nodeType | Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes. Read-only.
nodeTypedValue* | Contains the node value expressed in its defined data type. Read/write.
nodeTypeString* | Returns the node type in string form. Read-only.
nodeValue | Contains the text associated with the node. Read/write.
ownerDocument | Returns the root of the document that contains the node. Read-only.
parentNode | Contains the parent node. Read-only.
parsed* | Indicates the parsed status of the node and child nodes. Read-only.
prefix* | Returns the namespace prefix. Read-only.
previousSibling | Contains the previous sibling of the node in the parent's child list. Read-only.
specified* | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the DTD or schema. Read-only.
target | Specifies the target for the processing instruction. Read-only.
text* | Represents the text content of the node or the concatenated text representing the node and its descendants. Read/write.
xml* | Contains the XML representation of the node and all its descendants. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) DOM.

Methods

appendChild | Appends a new child as the last child of this node.
cloneNode | Clones a new node.
hasChildNodes | Provides a fast way to determine whether a node has children.
insertBefore | Inserts a child node to the left of the specified node or at the end of the list.
removeChild | Removes the specified child node from the list of children and returns it.
replaceChild | Replaces the specified old child node with the supplied new child node.
selectNodes* | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
selectSingleNode* | Applies the specified pattern-matching operation to this node's context and returns the first matching node.
transformNode* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation.
transformNodeToObject* | Processes this node and its children using the supplied XSLT style sheet and returns the resulting transformation in the supplied object.

* denotes an extension to the W3C DOM.

Events

None.

See Also

IXMLDOMNode | IXMLDOMProcessingInstruction


IXMLDOMSchemaCollection/XMLSchemaCache

Used by the schemas and namespaces properties on IXMLDOMDocument2.

[Script]

You can create XMLSchemaCache object in Microsoft® JScript® as follows.

var cache = new ActiveXObject("Msxml2.XMLSchemaCache");

In Microsoft Visual Basic® Scripting Edition (VBScript).

Dim cache
Set cache = CreateObject("Msxml2.XMLSchemaCache");

Example

The following example shows how to build a reusable schema cache.

  1. Load a document that references schemas through x-schema.
    var xmldoc = new ActiveXObject("Msxml2.DOMDocument");
xmldoc.async = false;
xmdoc.load("http://myserver/mydata.xml");
  2. Build a cache from the schemas loaded by your document.
    var cache = new ActiveXObject("Msxml2.XMLSchemaCache");
cache.addCollection(xmldoc.namespaces);
  3. Now you can use this cache in another document's load method.
    var xmldoc2 = new ActiveXObject("Msxml2.DOMDocument");
xmldoc2.async = false;
xmldoc2.schemas = cache;
xmldoc2.load("http://myserver/newdata.xml");

    "Xmldoc2" will load much faster because the schemas are cached.

[Visual Basic]

No example for this release.

[C/C++]

The IXMLDOMSchemaCollection implementation in Microsoft XML Parser (MSXML) 2.6 and 3.0 also supports the following interface through QueryInterface.

Interface | Usage
IID_EnumVARIANT | Returns an IEnumVARIANT implementation so the collection can be used in Microsoft Visual Basic For…Each statements. Enumerates the namespace Uniform Resource Identifiers (URIs).

Return Values

E_FAIL
Attempted to modify a read-only object; argument is not a valid schema; invalid namespace URI; or document is not ready.
E_INVALIDARG
The parameter is incorrect.
E_OUTOFMEMORY
Out of memory.
E_POINTER
Invalid pointer.

Example

import "msxml4.dll"
using namespace MSXML2;

#define CHECK_AND_RELEASE(pInterface)  \
if(pInterface) \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

#define RELEASE(pInterface)  \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

BOOL DOMDocument2nameSpaces()
{
   BOOL bResult = FALSE;
   short sResult = FALSE;
   IXMLDOMElement *pIXMLDOMElement=NULL;
   IXMLDOMSchemaCollection *pIXMLDOMSchemaCollection=NULL;
   IXMLDOMDocument2 *pIXMLDOMDocument2=NULL;
   HRESULT hr;
   BSTR bstrValue;

   try
   {
      hr=CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_SERVER,
         IID_IXMLDOMDocument2, (LPVOID*)(&pIXMLDOMDocument2));
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXMLDOMDocument2)
      {
         hr=pIXMLDOMDocument2->put_async(VARIANT_FALSE);
         if(SUCCEEDED(hr))
         {
            hr=pIXMLDOMDocument2->load(_variant_t(
               _T("d:\\inetpub\\wwwroot\\samplexmldtd.xml")), &sResult);
            if(SUCCEEDED(hr) && (sResult==VARIANT_TRUE))
            {
               hr=pIXMLDOMDocument2->get_namespaces(
                  &pIXMLDOMSchemaCollection);
               if(SUCCEEDED(hr))
               {
                  LONG uLength;

                  bResult=TRUE;
                  hr=pIXMLDOMSchemaCollection->get_length(&uLength);
                  if(SUCCEEDED(hr))
                  {
                     for(int iIndex=0; iIndex < uLength; iIndex++)
                     {
                        hr=pIXMLDOMSchemaCollection->get_namespaceURI(
                           iIndex, &bstrValue);
                        if(SUCCEEDED(hr))
                           ::MessageBox(NULL, bstrValue, _T("Namespace"),
                           MB_OK);
                     }
                  }
               }
            }
         }
         RELEASE(pIXMLDOMDocument2);
      }
   }
   catch(...)
   {
      CHECK_AND_RELEASE(pIXMLDOMDocument2);
      DisplayErrorToUser();
   }
   return bResult;
}

d:\\inetpub\\wwwroot\\samplexmldtd.xml

<?xml version='1.0'?>
<COLLECTION xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
  <BOOK>
    <TITLE>Cosmos</TITLE>
    <AUTHOR>Carl Sagan</AUTHOR>
    <PUBLISHER>Ballantine Books</PUBLISHER>
  </BOOK>
</COLLECTION>

Output (in a message box)

urn:schemas-microsoft-com:datatypes

Remarks

The XMLSchemaCache/IXMLDOMSchemaCollection object is free-threaded and can be used in multiple documents at the same time. A single schema document can belong to multiple schema collections and will remain read-only until it is removed from all collections. Schema documents belonging to a collection must be free-threaded.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

Version-Independent ProgID: Msxml2.XMLSchemaCache

Version-Independent CLSID: 373984C9-B845-449B-91E7-45AC83036ADE

Version-Dependent ProgID: Msxml2.XMLSchemaCache.3.0

Version-Dependent CLSID: f5078f34-c551-11d3-89b9-0000f81fe221

See Also

XMLSchemaCache/IXMLDOMSchemaCollection Members | IXMLDOMDocument2


XMLSchemaCache/IXMLDOMSchemaCollection Members

The methods and properties in this table are an extension to the Worldwide Web Consortium (W3C) DOM.

Properties

length Returns the number of namespaces currently in a collection. Read-only.

Methods

add | Adds a new schema to the schema collection and associates the given namespace URI with the specified schema.
addCollection | Adds schemas from another collection into the current collection and replaces any schemas that collide on the same namespace URI.
get | Returns a read-only Document Object Model (DOM) node that contains the <Schema> element.
namespaceURI (XMLSchemaCache/IXMLSchemaCollection) | Returns the namespace at the specified index.
remove | Removes the specified namespace from a collection.

Events

None.

See Also

IXMLDOMSchemaCollection/XMLSchemaCache


IXMLDOMSelection

Represents the list of nodes that match a given XSL Pattern or XML Path Language (XPath) expression.

[Script]

Example

In the following Microsoft® JScript® example, you can simply call the IXMLDOMSelection methods on the object returned from selectNodes.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.setProperty("SelectionLanguage", "XPath");
var selection = xmlDoc.selectNodes("//book");
var expr = selection.expr; //This returns "//book"
alert(expr);
[Visual Basic]

Example

In the following Microsoft Visual Basic® example, the selectNodes method returns IXMLDOMNodeList, so you have to cast the result of selectNodes into an IXMLDOMSelection.

Dim xmlDoc As New Msxml2.DOMDocument
Dim Selection As IXMLDOMSelection
Dim sExpr As String
xmlDoc.async = False
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.Load ("books.xml")
Set Selection = xmlDoc.selectNodes("//book")
expr = Selection.expr       ' This returns "//book"
MsgBox (expr)
[C/C++]

Example

In the following C/C++ example, IXMLDOMSelection inherits the threading model of the document that created it.

#import "msxml4.dll"
using namespace MSXML2;

#define CHECK_AND_RELEASE(pInterface)  \
if(pInterface) \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

#define RELEASE(pInterface)  \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

BOOL DOMSelectionDemo()
{
   BOOL bResult = FALSE;
   short sResult = FALSE;
   IXMLDOMSelection *pIXMLDOMSelection=NULL;
   IXMLDOMNodeList *pIXMLDOMNodeList=NULL;
   IXMLDOMNode *pIXMLDOMNode=NULL;
   IXMLDOMDocument2 *pIXMLDOMDocument2=NULL;
   BSTR bstrValue;
   HRESULT hr;

   try
   {
      hr=CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_SERVER,
               IID_IXMLDOMDocument2, (LPVOID*)(&pIXMLDOMDocument2));
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXMLDOMDocument2)
      {
         hr=pIXMLDOMDocument2->put_async(VARIANT_FALSE);
         if(SUCCEEDED(hr))
         {
            hr=pIXMLDOMDocument2->load(_variant_t(
      _T("d:\\inetpub\\wwwroot\\samplexmldtd.xml")), &sResult);
            if(SUCCEEDED(hr) && (sResult==VARIANT_TRUE))
            {
               hr=pIXMLDOMDocument2->selectNodes(
               _T("*/BOOK[TITLE='Cosmos']"), &pIXMLDOMNodeList);
               if(SUCCEEDED(hr))
               {
                  hr=pIXMLDOMNodeList->QueryInterface(IID_IXMLDOMSelection
                     ,(void**)&pIXMLDOMSelection );
                  if(SUCCEEDED(hr) && pIXMLDOMSelection)
                  {
                     LONG uLength;

                     bResult=TRUE;
                     hr=pIXMLDOMSelection->get_length(&uLength);
                     if(SUCCEEDED(hr))
                     {
                        for(int iIndex=0; iIndex < uLength; iIndex++)
                        {
                           // remove all the nodes from the list-display
                           // them as they are removed.
                           hr=pIXMLDOMSelection->removeNext(
                              &pIXMLDOMNode);
                           if(SUCCEEDED(hr) && pIXMLDOMNode)
                           {
                              hr=pIXMLDOMNode->get_text(&bstrValue);
                              if(SUCCEEDED(hr))
                                 ::MessageBox(NULL, bstrValue, _T("Node
                                  Text"), MB_OK);
                              RELEASE(pIXMLDOMNode);
                           }
                        }
                     }
                     RELEASE(pIXMLDOMSelection);
                  }
                  RELEASE(pIXMLDOMNodeList);
               }
            }
         }
         RELEASE(pIXMLDOMDocument2);
      }
   }
   catch(...)
   {
      CHECK_AND_RELEASE(pIXMLDOMNode);
      CHECK_AND_RELEASE(pIXMLDOMDocument2);
      CHECK_AND_RELEASE(pIXMLDOMNodeList);
      CHECK_AND_RELEASE(pIXMLDOMSelection);
      DisplayErrorToUser();
   }
   return bResult;
}

d:\\inetpub\\wwwroot\\samplexmldtd.xml

<?xml version='1.0'?>
<COLLECTION xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
  <BOOK>
    <TITLE>Cosmos</TITLE>
    <AUTHOR>Carl Sagan</AUTHOR>
    <PUBLISHER>Ballantine Books</PUBLISHER>
 </BOOK>
 <BOOK>
    <TITLE>Catwings</TITLE>
    <AUTHOR>Ursula K. Le Guin</AUTHOR>
    <PUBLISHER>Scholastic</PUBLISHER>
 </BOOK>
 <BOOK>
    <TITLE>Home Town</TITLE>
    <AUTHOR>Tracy Kidder</AUTHOR>
    <PUBLISHER>Random House</PUBLISHER>
 </BOOK>
</COLLECTION>

Output (in a message box)

Cosmos Carl Sagan Ballantine Books

Remarks

IXMLDOMSelection is created through the selectNodes method on IXMLDOMDocument2. IXMLDOMSelection is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

Version-Independent ProgID: Msxml2.DOMDocument, Msxml2.FreeThreadedDOMDocument

Version-Independent CSLID: F6D90F11-9C73-11D3-B32E-00C04F990BB4

Version-Dependent ProgID: Msxml2.DOMDocument.3.0, Msxml2.FreeThreadedDOMDocument.3.0

Version-Dependent CLSID: F5078F32-C551-11D3-89B9-0000F81FE221

See Also

IXMLDOMSelection Members


IXMLDOMSelection Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IXMLDOMNodeList.

The methods and properties in this table are an extension to the Worldwide Web Consortium (W3C) DOM.

Properties

context | Gets the node (subtree) that is applied to the selection.
expr | Gets or sets the XML Path Language (XPath) expression string. Read/write.
length (IXMLDOMNodeList) | Indicates the number of items in a collection. Read-only.

Methods

clone | Clones a copy of the current IXMLDOMSelection, with the same position and context.
getProperty | Returns a property.
item (IXMLDOMNodeList) | Allows random access to individual nodes within a collection. This method has no effect on the current position.
matches | Checks if the node that is passed is contained in the current collection.
nextNode | Returns the next node in the collection.
peekNode | Gets the next node that nextNode will return without advancing the line position.
removeAll | Removes all the nodes from the collection described by the IXMLDOMSelection.
removeNext | Removes the next node.
reset | Resets the iterator.

Events

None.

See Also

IXMLDOMNodeList | IXMLDOMSelection


IXMLDOMText

Represents the text content of an element or attribute.

[Script]

Example

The following script example creates an IXMLDOMText object (objText), and inserts it before the first child of the root. The insertBefore method returns another IXMLDOMText object, objText1.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var objText;
var objText1;
var objNode;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
objText = xmlDoc.createTextNode("Hello World");
objText1 = root.insertBefore(objText, root.firstChild);
alert(root.xml);
[Visual Basic]

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMText object (objText), and inserts it before the first child of the root. The insertBefore method returns another IXMLDOMText object, objText1.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim objText As IXMLDOMText
Dim objNode As IXMLDOMNode
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
Set objText = xmlDoc.createTextNode("Hello World")
Set objText1 = root.insertBefore(objText, root.firstChild)
MsgBox root.xml
[C/C++]

Example

The following C/C++ example creates and appends a new text node to the root document element.

#import "msxml4.dll"
using namespace MSXML2;

inline void TESTHR( HRESULT _hr )
   { if FAILED(_hr) throw(_hr); }

void XMLDOMText()
{
   try {
      IXMLDOMDocumentPtr docPtr;
      IXMLDOMNodePtr DOMNodePtr;
      IXMLDOMNamedNodeMapPtr DOMNamedNodeMapPtr;

      //init
      TESTHR(CoInitialize(NULL));
      TESTHR(docPtr.CreateInstance("msxml2.domdocument"));

      // load a document
      _variant_t varXml("C:\\book.xml");
      _variant_t varOut((bool)TRUE);
      varOut = docPtr->load(varXml);
      if ((bool)varOut == FALSE)
         throw(0);

      DOMNodePtr = docPtr->createTextNode("Hello World");

      docPtr->documentElement->appendChild(DOMNodePtr);

      MessageBox(NULL, _bstr_t(docPtr->xml), _T("New Document"), MB_OK);

   } catch(...)
   {
      MessageBox(NULL, _T("Exception occurred"), _T("Error"), MB_OK);
   }
   CoUninitialize();
}

Remarks

XML refers to this text content as character data and distinguishes it from markup, the tags that modify that character data. If there is no markup inside an element, that element's text is contained in a single IXMLDOMText object that is the child of the element. If there is markup inside an element, it is parsed into child elements that are siblings of the IXMLDOMText object(s). (The content of the markup elements also appears within text nodes, which are the children of the specific markup element.)

When a document is first made available to the XML Document Object Model (DOM), all text is normalized: there is only one text node for each block of text. Users can create adjacent text nodes that represent the contents of a given element without any intervening markup but should be aware that there is no way to represent the separations between these nodes, so they will not persist between XML DOM sessions.

The normalize method on the IXMLDOMElement object merges adjacent text nodes into a single node. You should normalize before starting any operations that depend on a particular document structure to ensure that subsequent sessions will operate on the same structure.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

IXMLDOMElement | IXMLDOMText Members | normalize Method


IXMLDOMText Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IXMLDOMCharacterData.

Properties

attributes | Contains the list of attributes for this node. Read-only.
baseName* | Returns the base name for the name qualified with the namespace. Read-only.
childNodes | Contains a node list containing the children nodes. Read-only.
data (IXMLDOMCharacterData) | Stores the node data depending on the node type. Read/write.
dataType* | Specifies the data type for this node. Read/write.
definition* | Returns the definition of the node in the document type definition (DTD) or schema. Read-only.
firstChild | Contains the first child of the node. Read-only.
lastChild | Returns the last child node. Read-only.
length (IXMLDOMCharacterData) | Specifies the length, in characters, of the data. Read-only.
namespaceURI* | Returns the Uniform Resource Identifier (URI) for the namespace. Read-only.
nextSibling | Contains the next sibling of the node in the parent's child list. Read-only.
nodeName | Contains the qualified name of the element, attribute, or entity reference, or a fixed string for other node types. Read-only.
nodeType | Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes. Read-only.
nodeTypedValue* | Contains the node value expressed in its defined data type. Read/write.
nodeTypeString* | Returns the node type in string form. Read-only.
nodeValue | Contains the text associated with the node. Read/write.
ownerDocument | Returns the root of the document that contains the node. Read-only.
parentNode | Contains the parent node. Read-only.
parsed* | Indicates the parsed status of the node and child nodes. Read-only.
prefix* | Returns the namespace prefix. Read-only.
previousSibling | Contains the previous sibling of the node in the parent's child list. Read-only.
specified | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the DTD or schema. Read-only.
text* | Represents the text content of the node or the concatenated text representing the node and its descendants. Read/write.
xml* | Contains the XML representation of the node and all its descendants. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) DOM.

Methods

appendChild | Appends a new child as the last child of the node.
appendData | Appends the supplied string to the existing string data.
cloneNode | Clones a new node.
deleteData | Deletes specified data.
hasChildNodes | Provides a fast way to determine whether a node has children.
insertBefore | Inserts a child node to the left of the specified node or at the end of the list.
insertData | Inserts a string at the specified offset.
removeChild | Removes the specified child node from the list of children and returns it.
replaceChild | Replaces the specified old child node with the supplied new child node.
selectNodes* | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
selectSingleNode* | Applies the specified pattern-matching operation to this node's context and returns the first matching node.
specified* | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the document type definition (DTD) or schema.
splitText | Splits this text node into two text nodes at the specified offset and inserts the new text node into the tree as a sibling that immediately follows this node.
substringData | Retrieves a substring of the full string from the specified range.
transformNode* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation.
transformNodeToObject* | Processes this node and its children using the supplied XSLT style sheet and returns the resulting transformation in the supplied object.

* denotes an extension to the W3C DOM.

Events

None.

See Also

IXMLDOMCharacterData


IXMLHTTPRequest

Provides client-side protocol support for communication with HTTP servers.

[Script]

Example

The following Microsoft® JScript® example posts a DOMDocument containing order information to an Active Server Pages (ASP) page on a server and returns the result as a new XML document.

<script language="JScript">
  function PostOrder(xmldoc)
  {
    var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    xmlhttp.Open("POST", "http://myserver/orders/processorder.asp", false);
    xmlhttp.Send(xmldoc);
    return xmlhttp.responseXML;
  }
</script>

The ASP page on the server loads the posted XML document, processes the order, and builds a resulting XML document.

<%@ language=javascript %>
<%
    Response.Expires = -1000;
    // Load the posted XML document.
    var doc = Server.CreateObject("Msxml2.DOMDocument");
    doc.load(Request);
    var result = Server.CreateObject("Msxml2.DOMDocument");
    // Now process the order and build the result document.
    Response.ContentType = "text/xml";
    result.save(Response);
%>
[Visual Basic]

The following Microsoft Visual Basic® example creates an XMLHTTP object and asks a server for an XML document. The server sends back an XML document that is displayed by the code snippet.

Private Sub Command1_Click()
  Dim HttpReq As New MSXML2.XMLHTTP

  HttpReq.open "GET", "http://XMLSampleServer/CatalogServer.asp", False
  HttpReq.send
  MsgBox HttpReq.responseText
End Sub
[C/C++]

The following C/C++ example creates an XMLHTTP object and asks a server for an XML document. The server sends back an XML document that is displayed by the code snippet.

#import "msxml4.dll"
using namespace MSXML2;

void XMLHttpRequestSample()
{
   IXMLHTTPRequestPtr pIXMLHTTPRequest = NULL;
   BSTR bstrString = NULL;
   HRESULT hr;

   try {
      hr=pIXMLHTTPRequest.CreateInstance("Msxml2.XMLHTTP");
      SUCCEEDED(hr) ? 0 : throw hr;

      hr=pIXMLHTTPRequest->open("GET", "http://XMLSampleServer/CatalogServer.asp", false);
      SUCCEEDED(hr) ? 0 : throw hr;

      hr=pIXMLHTTPRequest->send();
      SUCCEEDED(hr) ? 0 : throw hr;

      bstrString=pIXMLHTTPRequest->responseText;

      MessageBox(NULL, _bstr_t(bstrString), _T("Results"), MB_OK);

      if(bstrString)
      {
         ::SysFreeString(bstrString);
         bstrString = NULL;
      }

   } catch (...) {
      MessageBox(NULL, _T("Exception occurred"), _T("Error"), MB_OK);
      if(bstrString)
         ::SysFreeString(bstrString);
   }

}

Remarks

A client computer can use the XMLHTTP object (MSXML2.XMLHTTP) to send an arbitrary HTTP request, receive the response, and have the Microsoft® XML Document Object Model (DOM) parse that response.

This object is integrated with the Microsoft XML Parser (MSXML) to support sending the request body directly from, and parsing the response directly into, the MSXML DOM objects. When combined with the support for Extensible Stylesheet Language (XSL), the XMLHTTP component provides an easy way to send structured queries to HTTP servers and efficiently display the results with a variety of presentations.

The usual sequence is to call open, set any custom header information through setRequestHeader followed by send, and then to check one of the four different response properties.

The XMLHTTP object is supported in Microsoft Internet Explorer 5.0 or later.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

Version-Independent ProgID: Msxml2.XMLHTTP

Version-Independent CLSID: F6D90F16-9C73-11D3-B32E-00C04F990BB4

Version-Dependent ProgID: Msxml2.XMLHTTP.3.0

Version-Dependent CLSID: F5078F35-C551-11D3-89B9-0000F81FE221

See Also

IXMLHTTPRequest Members | DOMDocument


IXMLHTTPRequest Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IDispatch.

Properties

onreadystatechange (IXMLHTTPRequest)* | Specifies the event handler to be called when the readyState property changes. Read/write.
readyState (IXMLHTTPRequest) | Represents the state of the request. Read-only.
responseBody (IXMLHTTPRequest) | Represents only one of several forms in which the HTTP response can be returned. Read-only.
responseStream (IXMLHTTPRequest) | Represents only one of several forms in which the HTTP response can be returned. Read-only.
responseText (IXMLHTTPRequest) | Represents the response entity body as a string. Read-only.
responseXML (IXMLHTTPRequest) | Represents the parsed response entity body. Read-only.
status (IXMLHTTPRequest) | Represents the HTTP status code returned by a request. Read-only.
statusText (IXMLHTTPRequest) | Represents the HTTP response line status. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) Document Object Model (DOM).

Methods

abort | Cancels the current HTTP request.
getAllResponseHeaders (IXMLHTTPRequest) | Retrieves the values of all the HTTP headers.
getResponseHeader (IXMLHTTPRequest) | Retrieves the value of an HTTP header from the response body.
open (IXMLHTTPRequest) | Initializes an MSXML2.XMLHTTP request, and specifies the method, URL, and authentication information for the request.
send (IXMLHTTPRequest) | Sends an HTTP request to the server and receives a response.
setRequestHeader (IXMLHTTPRequest) | Specifies the name of an HTTP header.

Events

None.

See Also

IXMLHTTPRequest


IXSLProcessor

Used for transformations with compiled style sheets.

[C/C++]

IXSLProcessor is designed to handle asynchronous transformations. In this case, multiple calls to transform must be made, in which each call will transform as much as it can based on what is available from the input. In this scenario, the processor remains in READYSTATE_INTERACTIVE until the transform is complete.

[Script]

Example

var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xslProc;
xslDoc.async = false;
xslDoc.load("sample2.xsl");
xslt.stylesheet = xslDoc;
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
xslProc = xslt.createProcessor();
xslProc.input = xmlDoc;
xslProc.transform();
alert(xslProc.output);

Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html"/>
    <xsl:param name="param1"/>
    <xsl:template match="/">
        Hello
    </xsl:template>
    <xsl:template match="/" mode="edit">
        In Edit Mode
    </xsl:template>
    <xsl:template match="/" mode="view">
        In View Mode
    </xsl:template>
</xsl:stylesheet>
[Visual Basic]

Example

Dim xslt As New Msxml2.XSLTemplate
Dim xslDoc As New Msxml2.FreeThreadedDOMDocument
Dim xmlDoc As New Msxml2.DOMDocument
Dim xslProc As IXSLProcessor
xslDoc.async = False
xslDoc.Load "sample2.xsl"
Set xslt.stylesheet = xslDoc
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set xslProc = xslt.createProcessor()
xslProc.input = xmlDoc
xslProc.Transform
MsgBox xslProc.output

Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html"/>
    <xsl:param name="param1"/>
    <xsl:template match="/">
        Hello
    </xsl:template>
    <xsl:template match="/" mode="edit">
        In Edit Mode
    </xsl:template>
    <xsl:template match="/" mode="view">
        In View Mode
    </xsl:template>
</xsl:stylesheet>
[C/C++]

Example

#import "msxml4.dll"
using namespace MSXML2;

#define CHECK_AND_RELEASE(pInterface)  \
if(pInterface) \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

#define RELEASE(pInterface)  \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

BOOL XSLProcessorDemo()
{
   BOOL bResult = FALSE;
   short sResult = FALSE;
   HRESULT hr;
   IXMLDOMDocument2 *pStyleSheet=NULL;
   IXMLDOMDocument2 *pDOMObject=NULL;
   IXSLTemplate *pIXSLTemplate=NULL;
   IXSLProcessor *pIXSLProcessor=NULL;
   VARIANT varValue;

   try
   {
      hr = CoCreateInstance(CLSID_XSLTemplate, NULL, CLSCTX_SERVER,
            IID_IXSLTemplate, (LPVOID*)(&pIXSLTemplate));
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXSLTemplate)
      {
         hr=CoCreateInstance(CLSID_FreeThreadedDOMDocument, NULL,
               CLSCTX_SERVER, IID_IXMLDOMDocument2,
               (LPVOID*)(&pStyleSheet));
         SUCCEEDED(hr) ? 0 : throw hr;

         if(pStyleSheet)
         {
            hr=pStyleSheet->put_async(VARIANT_FALSE);
            if(SUCCEEDED(hr))
            {
               hr=pStyleSheet->load(_variant_t
                  (_T("d:\\inetpub\\wwwroot\\samplexsl.xml")), &sResult);
               if(SUCCEEDED(hr) && (sResult==VARIANT_TRUE))
               {
                  hr=pIXSLTemplate->putref_stylesheet(pStyleSheet);
                  if(SUCCEEDED(hr))
                  {
                     hr=pIXSLTemplate->createProcessor(&pIXSLProcessor);
                     SUCCEEDED(hr) ? 0 : throw hr;
                     if(pIXSLProcessor)
                     {
                        hr=CoCreateInstance(CLSID_DOMDocument, NULL,
                           CLSCTX_SERVER, IID_IXMLDOMDocument2,
                           (LPVOID*)(&pIXMLDOMDocument));
                        SUCCEEDED(hr) ? 0 : throw hr;

                        if(pIXMLDOMDocument)
                        {
                           hr=pIXMLDOMDocument->put_async(VARIANT_FALSE);
                           if(SUCCEEDED(hr))
                           {
                              hr=pIXMLDOMDocument->load(_variant_t(
                  _T("d:\\inetpub\\wwwroot\\sampleXSLWithObject.xml")), &sResult);
                              if(SUCCEEDED(hr) && (sResult==VARIANT_TRUE))
                              {
                                 hr=pIXSLProcessor->put_input(_variant_t
                                    (pIXMLDOMDocument));
                                 if(SUCCEEDED(hr))
                                 {
                                    hr=CoCreateInstance(
                                       CLSID_FreeThreadedDOMDocument,
                                       NULL, CLSCTX_SERVER,
                                       IID_IXMLDOMDocument2,
                                       (LPVOID*)(&pDOMObject));
                                    if(SUCCEEDED(hr) && pDOMObject)
                                    {
                                       hr=pDOMObject->put_async(
                                          VARIANT_FALSE);
                                       if(SUCCEEDED(hr))
                                       {
                                          hr=pDOMObject->loadXML(
                                          _T("<foo>foo</foo>"), &sResult);
                                          if(SUCCEEDED(hr))
                                          {
                                             hr=pIXSLProcessor->addObject(
                                                pDOMObject, _T("urn:my-
                                                object"));
                                             if(SUCCEEDED(hr))
                                                bResult=TRUE;
                                          }
                                       }
                                    }

                                    hr=pIXSLProcessor->transform(
                                       &sResult);
                                    if(SUCCEEDED(hr)&&(sResult==
                                       VARIANT_TRUE))
                                    {
                                       pIXSLProcessor->get_output(
                                          &varValue);
                                       ::MessageBox(NULL,
                                          _bstr_t(varValue),
                                          _T("Transformed Output"),
                                          MB_OK);
                                    }
                                    RELEASE(pDOMObject);
                                 }
                              }
                           }
                           RELEASE(pIXMLDOMDocument);
                        }
                     }
                  }
               }
            }
            RELEASE(pStyleSheet);
         }
         RELEASE(pIXSLTemplate);
      }
   }
   catch(...)
   {
      CHECK_AND_RELEASE(pIXSLTemplate);
      CHECK_AND_RELEASE(pStyleSheet);
      CHECK_AND_RELEASE(pIXMLDOMDocument);
      CHECK_AND_RELEASE(pDOMObject);
      DisplayErrorToUser();
   }
   return bResult;
}

The style sheet—"d:\\inetpub\\wwwroot\\sampleXSLWithObject.xml"

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       version="1.0" xmlns:myObj="urn:my-object">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:element name="bar">
<xsl:value-of select="myObj:get-text()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

Output (in a message box)

<?xml version="1.0" encoding="UTF-16"?>
<bar>
foo
</bar>

Remarks

The createProcessor method returns IXSLProcessor. The processor has a transform method that takes the input data, applies the XSL Transformations (XSLT) style sheet defined in the IXSLTemplate, and writes the result to the specified output stream.

This XSL processor is completely independent of the transformNode and transformNodeToObject methods on DOMDocument. In particular, when you transform XML using IXSLProcessor, the ontransformnode event is not fired on DOMDocument.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

Version-Independent ProgID: Msxml2.XSLTemplate

Version-Independent CLSID: 2933BF94-7B36-11d2-B20E-00C04F983E60

Version-Dependent ProgID: Msxml2.XSLTemplate.3.0

Version-Dependent CLSID: F5078F36-C551-11D3-89B9-0000F81FE221

See Also

IXSLProcessor Members


IXSLProcessor Members

The methods and properties in this table are an extension to the Worldwide Web Consortium (W3C) DOM.

Properties

input | Specifies which XML input tree to transform. Read/write.
output | Gets a custom output to write the result of the transformation. Read/write.
readyState (IXSLProcessor) | Returns the current state of the processor. Read-only.
startMode | Returns the base name part of the start mode, a qualified name. Read-only.
startModeURI | Returns the namespace Uniform Resource Identifier (URI) part of the start mode, the qualified name. Read-only.
stylesheet (IXSLProcessor) | Provides the Extensible Stylesheet Language (XSL) style sheet that is to be compiled into the XSL template. Read-only.
ownerTemplate | Returns the style sheet template that was used to create IXSLProcessor.

Methods

addObject | Adds objects into a style sheet.
addParameter | Adds parameters into an XSL Transformations (XSLT) style sheet.
reset (IXSLProcessor) | Resets the state of the processor to the state it was in prior to calling transform.
setStartMode | Performs subsets of larger XSLT transformations by selecting the XSLT mode with which to start. This minimizes the amount of XSLT processing.
transform | Starts the transformation process or resumes a previously failed transformation.

Events

None.

See Also

IXSLProcessor


IXSLTemplate

Used for caching compiled XSL Transformations (XSLT) templates.

[Script]

No script example for this release.

[Visual Basic]

No Microsoft Visual Basic® example for this release.

[C/C++]

Example

The following C++ example demonstrates the use of a single style sheet with multiple XML files. The style sheet is loaded once and cached into the IXSLTemplate object.

#import "msxml4.dll"
using namespace MSXML2;

#define CHECK_AND_RELEASE(pInterface)  \
if(pInterface) \
{\
pInterface->Release();\
pInterface = NULL;\
}\

#define RELEASE(pInterface)  \
{\
pInterface->Release();\
pInterface = NULL;\
}\

BOOL XSLTemplateDemo()
{
   BOOL bResult = FALSE;
   short sResult = FALSE;
   IXMLDOMDocument2 *pStyleSheet=NULL;
   IXMLDOMDocument2 *pIXMLDOMDocument2 =NULL;
   IXSLTemplate *pIXSLTemplate=NULL;
   IXSLProcessor *pIXSLProcessor=NULL;
   IXMLDOMDocument2 *pIXMLDOMDocument=NULL;
   HRESULT hr;
   VARIANT varValue;

   try
   {
      hr = CoCreateInstance(CLSID_XSLTemplate, NULL, CLSCTX_SERVER,
         IID_IXSLTemplate, (LPVOID*)(&pIXSLTemplate));
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXSLTemplate)
      {
         hr=CoCreateInstance(CLSID_FreeThreadedDOMDocument, NULL,
                  CLSCTX_SERVER, IID_IXMLDOMDocument2,
                  (LPVOID*)(&pStyleSheet));
         SUCCEEDED(hr) ? 0 : throw hr;

         if(pStyleSheet)
         {
            hr=pStyleSheet->put_async(VARIANT_FALSE);
            if(SUCCEEDED(hr))
            {
               hr=pStyleSheet->load(_variant_t(
               _T("d:\\inetpub\\wwwroot\\samplexsl.xml")), &sResult);
               if(SUCCEEDED(hr) && (sResult==VARIANT_TRUE))
               {
                  hr=pIXSLTemplate->putref_stylesheet(pStyleSheet);
                  if(SUCCEEDED(hr))
                  {
                     hr=pIXSLTemplate->createProcessor(&pIXSLProcessor);
                     SUCCEEDED(hr) ? 0 : throw hr;
                     if(pIXSLProcessor)
                     {
                        hr=CoCreateInstance(CLSID_DOMDocument, NULL,
                              CLSCTX_SERVER, IID_IXMLDOMDocument2,
                                    (LPVOID*)(&pIXMLDOMDocument));
                        SUCCEEDED(hr) ? 0 : throw hr;

                        if(pIXMLDOMDocument)
                        {
                           hr=pIXMLDOMDocument->put_async(VARIANT_FALSE);
                           if(SUCCEEDED(hr))
                           {
                              hr=pIXMLDOMDocument->load(_variant_t(
                           _T("d:\\inetpub\\wwwroot\\samplexmldtd.xml")),
                                 &sResult);
                              if(SUCCEEDED(hr) && (sResult==VARIANT_TRUE))
                              {
                                 hr=pIXSLProcessor->put_input(_variant_t(
                                    pIXMLDOMDocument));
                                 if(SUCCEEDED(hr))
                                 {
                                    hr=pIXSLProcessor->transform(
                                             &sResult);
                                    if(SUCCEEDED(hr)&&(sResult==
                                                VARIANT_TRUE))
                                    {
                                       pIXSLProcessor->get_output(
                                                &varValue);
                                       ::MessageBox(NULL,
                                          _bstr_t(varValue),
                                          _T("Transformed
                                             Output"), MB_OK);
                                    }
                                 }
                              }
                           }
                           RELEASE(pIXMLDOMDocument);
                        }
                           // Load another document.
                        hr=CoCreateInstance(CLSID_DOMDocument, NULL,
                              CLSCTX_SERVER, IID_IXMLDOMDocument2,
                                 (LPVOID*)(&pIXMLDOMDocument2));
                        SUCCEEDED(hr) ? 0 : throw hr;

                        if(pIXMLDOMDocument2)
                        {
                           hr=pIXMLDOMDocument2->put_async(VARIANT_FALSE);
                           if(SUCCEEDED(hr))
                           {
                              // Load some XML into the document.
                              hr=pIXMLDOMDocument2->loadXML(
                                 _T("<COLLECTION\ xmlns:dt=\"urn:schemas-
                                 microsoft-\ com:datatypes\">\
                                 <DATE dt:dt=\"datetime\">1998-10-
                                       13T15:56:00\
                                          </DATE><BOOK><TITLE>Cosmos</TITLE> \
                                 <AUTHOR>Carl Sagan</AUTHOR> \
                                 <PUBLISHER>Ballantine Books</PUBLISHER> \
                                 </BOOK> \
                                 </COLLECTION>"), &sResult);
                              if(SUCCEEDED(hr) && (sResult==VARIANT_TRUE))
                              {
                                 // Use the same processor.
                                 hr=pIXSLProcessor->put_input(_variant_t(
                                    pIXMLDOMDocument2));
                                 if(SUCCEEDED(hr))
                                 {
                                    hr=pIXSLProcessor->transform(
                                             &sResult);
                                    if(SUCCEEDED(hr)&&(sResult==
                                                VARIANT_TRUE))
                                    {
                                       pIXSLProcessor->get_output(
                                                &varValue);
                                       ::MessageBox(NULL,
                                          _bstr_t(varValue),
                                          _T("Transformed
                                    Output"), MB_OK);
                                    }
                                 }
                              }
                           }
                           RELEASE(pIXMLDOMDocument2);
                        }
                        RELEASE(pIXSLProcessor);
                     }
                  }
               }
            }
            RELEASE(pStyleSheet);
         }
         RELEASE(pIXSLTemplate);
      }
   }
   catch(...)
   {
      CHECK_AND_RELEASE(pIXSLProcessor);
      CHECK_AND_RELEASE(pIXSLTemplate);
      CHECK_AND_RELEASE(pStyleSheet);
      CHECK_AND_RELEASE(pIXMLDOMDocument);
      CHECK_AND_RELEASE(pIXMLDOMDocument2);
      DisplayErrorToUser();
   }
   return bResult;
}

Remarks

Before the Microsoft® XML Parser (MSXML) 2.6, every call to transformNode or transformNodeToObject had to recompile the style sheet because the style sheet was simply passed as an IXMLDOMNode. You can increase performance by caching the compiled style sheet and reusing it with the IXSLTemplate object.

To cache a compiled XSLT style sheet, load an XSLT style sheet into an IXSLTemplate object. This object is free-threaded and stateless, so it can be stored in shared Active Server Pages (ASP) application state. Then to transform a given document using this template, create an IXSLProcessor object using the createProcessor method. The IXSLProcessor object stores the state for one transform call and has a rental-threading model.

This object is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

Version-Independent ProgID: Msxml2.XSLTemplate

Version-Independent CLSID: 2933BF94-7B36-11D2-B20E-00C04F983E60

Version-Dependent ProgID: Msxml2.XSLTemplate.3.0

Version-Dependent CLSID: F5078F36-C551-11D3-89B9-0000F81FE221

See Also

IXSLTemplate Members


IXSLTemplate Members

The methods and properties in this table are an extension to the Worldwide Web Consortium (W3C) DOM.

Properties

stylesheet Provides the Extensible Stylesheet Language (XSL) style sheet to compile into an XSL template.

Methods

createProcessor Creates a rental-model XSLProcessor that will use this template.

Events

None.

See Also

IXSLTemplate


IXTLRuntime

Part of the older Extensible Stylesheet Language (XSL) implementation. Implements the following methods, which can be called from within XSL Transformations (XSLT) style sheets.

  • absoluteChildNumber
  • ancestorChildNumber
  • childNumber
  • depth
  • formatDate
  • formatIndex
  • formatNumber
  • formatTime
  • uniqueID
[Visual Basic, Script, C/C++]

For more information, see XSLT Reference.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

See Also

IXTLRuntime Members | XSLT Reference


IXTLRuntime Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IXMLDOMNode.

Properties

attributes | Contains the list of attributes for this node. Read-only.
baseName* | Returns the base name for the name qualified with the namespace. Read-only.
childNodes | Contains a node list containing the children nodes. Read-only.
dataType* | Specifies the data type for this node. Read/write.
definition* | Returns the definition of the node in the document type definition (DTD) or schema. Read-only.
firstChild | Contains the first child of the node. Read-only.
lastChild | Returns the last child node. Read-only.
namespaceURI (IXMLDOMNode)* | Returns the Uniform Resource Identifier (URI) for the namespace. Read-only.
nextSibling | Contains the next sibling of this node in the parent's child list. Read-only.
nodeName | Contains the qualified name of the element, attribute, or entity reference, or a fixed string for other node types. Read-only.
nodeType | Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes. Read-only.
nodeTypedValue* | Contains the node value expressed in its defined data type. Read/write.
nodeTypeString* | Returns the node type in string form. Read-only.
nodeValue | Contains the text associated with the node. Read/write.
ownerDocument | Returns the root of the document that contains the node. Read-only.
parentNode | Contains the parent node. Read-only.
parsed* | Indicates the parsed status of the node and child nodes. Read-only.
prefix* | Returns the namespace prefix. Read-only.
previousSibling | Contains the previous sibling of the node in the parent's child list. Read-only.
specified* | Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the DTD or schema. Read-only.
text* | Represents the text content of the node or the concatenated text representing the node and its descendants. Read/write.
xml* | Contains the XML representation of the node and all its descendants. Read-only.

* denotes an extension to the Worldwide Web Consortium (W3C) DOM.

Methods

absoluteChildNumber | Returns the number of the node that is relative to all siblings.
ancestorChildNumber | Returns the number of the nearest ancestor of a node with the requested node name.
appendChild | Appends a new child as the last child of the node.
childNumber | Returns the number of the node relative to siblings of the same node name.
cloneNode | Clones a new node.
depth | Returns the depth within the document tree at which the specified node appears.
formatDate | Formats the date using the specified formatting options.
formatIndex | Formats the index integer using the specified numerical system.
formatNumber | Formats the number using the specified format.
formatTime | Formats the time using the specified formatting options.
hasChildNodes | Provides a fast way to determine whether a node has children.
insertBefore | Inserts a child node to the left of the specified node or at the end of the list.
removeChild | Removes the specified child node from the list of children and returns it.
replaceChild | Replaces the specified old child node with the supplied new child node.
selectNodes* | Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.
selectSingleNode* | Applies the specified pattern-matching operation to this node's context and returns the first matching node.
transformNode* | Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation.
transformNodeToObject* | Processes this node and its children using the supplied XSLT style sheet and returns the resulting transformation in the supplied object.
uniqueID | Returns the unique identifier for the supplied node.

* denotes an extension to the W3C DOM.

Events

None.

See Also

IXTLRuntime | IXMLDOMNode


IServerXMLHTTPRequest/ServerXMLHTTP

Provides methods and properties that enable you to establish an HTTP connection between files or objects on different Web servers.

The ServerXMLHTTP object offers functionality similar to that of the XMLHTTP object. Unlike XMLHTTP, however, the ServerXMLHTTP object does not rely on the WinInet control for HTTP access to remote XML documents. ServerXMLHTTP uses a new HTTP client stack. Designed for server applications, this server-safe subset of WinInet offers the following advantages:

  • Reliability—The HTTP client stack offers longer uptimes. WinInet features that are not critical for server applications, such as URL caching, auto-discovery of proxy servers, HTTP/1.1 chunking, offline support, and support for Gopher and FTP protocols are not included in the new HTTP subset.
  • Security—The HTTP client stack does not allow a user-specific state to be shared with another user's session. ServerXMLHTTP provides support for client certificates.
    Note For more information about the limitations of the WinInet control, see Other Resources WinInet Limits Connections Per Server.

Usage

The ServerXMLHTTP object is commonly used to:

  • Receive XML documents from an Active Server Pages (ASP) page on a local or remote Web server (HTTP GET).
  • Post XML documents to an ASP page on a local or remote Web server (HTTP POST).
  • Post and process response XML documents from an ASP page (HTTP POST).

You can use the ServerXMLHTTP object either indirectly using the setProperty method of DOMDocument or directly using the ServerXMLHTTP object itself. For examples of these two approaches, as well as examples of how to use the ServerXMLHTTP security options and how to use ServerXMLHTTP in a multitiered environment, see IServerXMLHTTPRequest/ServerXMLHTTP Examples.

Remarks

The ServerXMLHTTP open method makes the connection between servers and the send method sends the request.

You can read the response using one of the four following properties: responseBody, responseStream, responseText, and responseXML.

[C/C++]

With ServerXMLHTTP, the usual sequence is to call open, set any custom header information through setRequestHeader, call send, and then check one of the four response properties.

For example, an ASP, Microsoft® Visual Basic®, or C++ component on a server computer can send an HTTP request to another server and then receive the response as a stream or XML document object. The response can then be fed to downstream clients, saved to a file on the server, or combined with other XML data (potentially collected from other Web servers).

ServerXMLHTTP offers additional benefits for transporting XML data:

  • ServerXMLHTTP maintains state, so transactional XML data can be used in business applications that require real-time responses.
  • ServerXMLHTTP allows you to serve the response object as a stream or Document Object Model (DOM) object. As a stream, this offers considerable performance benefits when moving data through the HTTP protocol.

ServerXMLHTTP offers backward compatibility with XMLHTTP. Source code (JScript, Visual Basic Scripting Edition, Visual Basic, or C++) that uses the XMLHTTP component can be easily modified to use the new ServerXMLHTTP component.

The maximum number of instances that can exist simultaneously within a single process is 5,460. A similar limitation applies to the XMLHTTP component. However, other factors, such as available memory, CPU processing capacity, or available socket connections can further limit the number of instances that can be active simultaneously. Partition the server application into multiple processes if this limit becomes a bottleneck.

The IServerXMLHTTPRequest interface inherits from IXMLHTTPRequest and extends it with the following four new methods: getOption, setOption, waitForResponse, and setTimeouts.

Requirements

Supported platforms include Microsoft Windows® 2000, or Microsoft Windows NT® 4.0 with Microsoft Internet Explorer 5.01 (or later) installed. ServerXMLHTTP fails on other platforms, such as Microsoft Windows 95 or Microsoft Windows 98.

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

Version-Independent ProgID: Msxml2.SERVERXMLHTTP

Version-Independent CLSID: afba6b42-5692-48ea-8141-dc517dcf0ef1

Version-Dependent ProgID: Msxml2.ServerXMLHTTP.3.0

Version-Dependent CLSID: afb40ffd-b609-40a3-9828-f88bbe11e4e3

See Also

IXMLHTTPRequest | IServerXMLHTTPRequest/ServerXMLHttp Members


IServerXMLHTTPRequest/ServerXMLHTPP Examples

Microsoft XML 4.0 Technology Preview - XML Reference

IServerXMLHTTPRequest/ServerXMLHTTP Examples

The examples in this section cover:

  • Using the setProperty method of DOMDocument
  • Using ServerXMLHTTP Directly
  • Using the ServerXMLHTTP Security Options
  • Using ServerXMLHTTP in a Multitiered Environment


Using the setProperty method of DOMDocument

The ServerHTTPRequest property flag indicates that the parser should use the server-safe ServerXMLHTTP object, instead of the DOMDocument object, to synchronously load an XML document from a server. As with all property flags, the ServerHTTPRequest property must be set before calling the load method of the DOMDocument; otherwise, the parser ignores the property flag.

To set the ServerHTTPRequest property flag, you need to use the setProperty method of the DOMDocument object. Using the setProperty method to set the ServerHTTPRequest property flag to true creates a background ServerXMLHTTP object, separate from the DOMDocument.

Once the property flag is set, calling the load method of DOMDocument results in the background ServerXMLHTTP object performing the actual loading of the XML document and, upon successfully loading this document, transparently passing the document to the DOMDocument object.

Note There are no Microsoft® Visual Basic® or C++ examples for this release.

Example

The following ASP server script demonstrates the use of the setProperty method of DOMDocument, which creates a background ServerXMLHTTP object. This background ServerXMLHTTP object transparently performs the loading of an XML response from a Web server and then hands the results to the DOMDocument.

<%@language=JScript%>
<%
   var objXMLDocument;
   objXMLDocument = Server.CreateObject("MSXML2.DOMDocument");
   objXMLDocument.async = false;
   objXMLDocument.setProperty ("ServerHTTPRequest", true);
   objXMLDocument.load ("http://someotherserver/respond.asp");
   Response.ContentType = "text/xml";
   Response.Write (objXMLDocument.xml);
%>


Using ServerXMLHTTP Directly

Using the ServerXMLHTTP object directly offers much greater procedural control than that of the setProperty method of DOMDocument. Instead of merely retrieving XML responses from a remote sever, the ServerXMLHTTP object allows developers to use the HTTP methods, GET and POST, as well as the ability to handle basic security logons.

Note There are no Microsoft® Visual Basic® or C++ examples for this release.

Using ServerXMLHTTP to GET XML results from an ASP page

In the following example, ServerXMLHTTP retrieves an XML response from an ASP page over HTTP. By using GET, the example is able to send a request without actually transferring any data to the Web server.

The responseXML property of the objSrvHTTP object contains the XML response from the Web server. The example program writes this response to the browser's output by first informing the browser that the response to be received is XML ("text/xml"). Next, the program passes the response directly to Response object for displaying onscreen.

Example

<%@language=JScript%>
<%
   var objSrvHTTP;
   objSrvHTTP = Server.CreateObject ("MSXML2.ServerXMLHTTP");
   objSrvHTTP.open ("GET","http://someotherserver/respond.asp", false);
   objSrvHTTP.send ();
   Response.ContentType = "text/xml";
   Response.Write (objSrvHTTP.responseXML.xml);
%>

Using ServerXMLHTTP to POST XML to an ASP page

In the following example, ServerXMLHTTP uses HTTP to send XML data to an Active Server Page (ASP) page. Unlike the preceding example that used GET, this example uses POST. The POST method sends data, along with the request, to the Web server.

As in the previous example, the program writes the response to the browser's output by setting the ContentType to "text/xml" and passing the response to the Response object.

Example

<%@language=JScript%>
<%
   var objSrvHTTP;
   var objXMLDocument;
   objSrvHTTP = Server.CreateObject ("MSXML2.ServerXMLHTTP");
   objXMLDocument = Server.CreateObject ("MSXML2.DOMDocument");

   objXMLDocument.async= false;
   objXMLDocument.loadXML ("<msg><id>1</id></msg>");

   objSrvHTTP.open ("POST","http://someotherserver/respond.asp",false);
   objSrvHTTP.send (objXMLDocument);
   Response.ContentType = "text/xml";
   Response.Write (objSrvHTTP.responseXML.xml);
%>

Using ServerXMLHTTP to POST and Process XML

In the following example, ServerXMLHTTP sends an XML document to an ASP page on a Web server and passes its XML response to a waiting DOMDocument for processing.

Example

<%@language=Jscript%>
<%
   var objSrvHTTP;
   var objXMLSend;
   var objXMLReceive;
   objSrvHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP");
   objXMLSend = Server.CreateObject("MSXML2.DOMDocument");
   objXMLReceive = Server.CreateObject("MSXML2.DOMDocument");

   objXMLSend.async = false;
   objXMLSend.loadXML ("<msg><id>2</id></msg>");

   objSrvHTTP.open ("POST","http://someotherserver/respond.asp",false);
   objSrvHTTP.send (objXMLSend);
   objXMLReceive = objSrvHTTP.responseXML;
   Response.ContentType = "text/xml";
   Response.Write (objXMLReceive.xml);
%>


Using the ServerXMLHTPP Security Options

Microsoft XML 4.0 Technology Preview - XML Reference

Using the ServerXMLHTTP Security Options

The bstrUser and bstrPassword parameters of the open method of ServerXMLHTTP allow users to log onto Web servers secured with basic authentication. Both the bstrUser and bstrPassword parameters are sent in clear text (data that is transmitted as clearly readable text characters).

The following example demonstrates how to use the optional bstrUser and bstrPassword parameters of the open method of ServerXMLHTTP to retrieve an XML document from a Web server secured with basic authentication.

Note There are no Microsoft® Visual Basic® or C++ examples for this release.

Example

<%@language=Jscript%>
<%
   var objSrvHTTP;
   objSrvHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP");
   objSrvHTTP.open ("GET","http://someotherserver/secure.asp",false, _
                       "testuser", "testpassword";
   objSrvHTTP.send ();
   Response.ContentType = "text/xml";
   Response.Write (objSrvHTTP.responseXML.xml);
%>


ServerXMLHTTP/IServerXMLHTTPRequest

Microsoft XML 4.0 Technology Preview - XML Reference

Using ServerXMLHTTP in a Multitiered Environment

The following example shows how ServerXMLHTTP can be used to access a news service on a backend server and deliver it to a Web client.

Note There are no Microsoft® Visual Basic® or C++ examples for this release.

Request on the Presentation Tier

A simple Web page, latestnews.asp, contains a link to the ServerXMLHTTP.asp page on the business tier server.

<html>
<head>
   <title>Latest News</title>
</head>

<body>
<a href="http://myserver/myproject/ServerXMLHttp.asp">Latest News</a>
</body>
</html>

Request on the Business Tier

The ServerXMLHTTP.asp page resides on the business or middle tier. This page contains Microsoft® JScript® that opens a connection to a NewsService.asp page on a server at the data services tier.

<%@language=JScript%>
<%
var srvXMLHTTP
srvXMLHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP");
srvXMLHTTP.open ("GET", "http://dataserver/news/NewsService.asp", false);
srvXmlHttp.send();
newsElement = srvXMLHTTP.responseXML.selectSingleNode("/news/story1");
%>

<html>
<body>
<p>Top News Story<p>
<%Response.Write(newsElement.text);%>
</body>
</html>

Response on the Data Services Tier

The NewsService.asp page resides on the data services or middle tier. This page contains JScript that loads an XML document, news.xml, into a DOMDocument object named Result, and then saves the object directly to the Response object, which is returned to ServerXMLHTTP.asp on the business tier.

<%@language=JScript%>
<%
var Result = Server.CreateObject("MSXML2.DOMDocument");
Result.async = false;
Result.load(Server.MapPath("news.xml"));
Response.ContentType = "text/xml";
Result.save(Response);
%>
Note A document comprised of the latest news stories collected by a news service can be quite large. For this example, the news.xml document loaded by NewsService.asp is small and simple.
<?xml version ="1.0"?>
<news>
   <story1>Here is the top news story…</story1>
   <story2>News is the next news story.</story2>
</news>

Response on the Business Tier

ServerXMLHTTP.asp handles the response on the business tier. In this case, ServerXMLHTTP.asp loads the response into the xmlResult (DOMDocument) object. The DOM selects a single node from the document using the selectSingleNode method of DOMDocument, setting the results to the newsElement object. The program then writes the text property of the newsElement object (along with HTML) to the Web page on the requesting client computer on the presentation tier.

<%@language=JScript%>
<%
var srvXMLHTTP;
srvXMLHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP");
srvXMLHTTP.open ("GET", "http://dataserver/news/NewsService.asp", false);
srvXMLHTTP.send();
newsElement = srvXMLHTTP.responseXML.selectSingleNode("/news/story1");
%>

<html>
<body>
<p>Top News Story<p>
<%Response.Write(newsElement.text);%>
</body>
</html>

Response on the Presentation Tier

The user sees the following output in the Web browser.

Top News Story
Here is the top news story…


Using the WinHTTP Proxy Configuration Utility

The WinHTTP proxy configuration utility, proxycfg.exe, configures WinHTTP to access HTTP and HTTPS servers through a proxy server. Because the ServerXMLHTTP object depends on WinHTTP proxy settings, an administrator can use the proxycfg.exe utility as part of the deployment and installation process of an application that uses WinHTTP. The administrator who runs proxycfg.exe must have local administrator privileges so that proxycfg.exe can update the registry of the local computer. WinHTTP proxy settings are per-machine, not per-user.

Note WinHTTP proxy settings are separate from the proxy settings in Microsoft® Internet Explorer.

Configuration of WinHTTP proxy settings must be done using the proxycfg.exe utility; these settings cannot be configured through Control Panel. With the proxycfg.exe utility, an administrator can also specify an optional list of host names to bypass the proxy server and be accessed directly. The proxycfg.exe tool can also configure WinHTTP to access all servers directly.

To download the proxy configuration utility

  • To download the proxy configuration utility, go the Other Resources XML Development Center.
    Important After using proxycfg.exe to update the registry, the previous settings cannot be restored.

Usage

The following examples show the syntax used for various commands in the proxycfg.exe utility.

proxycfg
This command displays the current WinHTTP proxy settings.
proxycfg -d
This command specifies that all HTTP and HTTPS servers should be accessed directly. Use this command if there is no proxy server.
proxycfg -p proxy-server-list optional-bypass-list
This command specifies one or more proxy servers, and an optional list of hosts that should be accessed directly. If a proxy server is not specified for a given protocol and that server is not in the bypass list, the -p option specifies that the server cannot be accessed at all.
proxycfg -d -p proxy-server-list optional-bypass-list
This command specifies one or more proxy servers, and an optional list of hosts that should be accessed directly. If a proxy server is not specified for the given protocol, the -d option specifies that the server should be accessed directly instead.
proxycfg -u
This command imports the Internet Explorer proxy settings of the current user. WinHTTP does not support auto-discovery and configuration script-based proxy settings.

The following table describes how to use both the proxy-server-list and optional-bypass-list parameters.

Parameter Description of use
proxy-server-list Proxies are specified in a space-delimited string. The proxy listings can contain the port number used to access the proxy.

Proxy servers can be listed to use a specific protocol. The valid protocols are HTTP or HTTPS. The syntax for a proxy listing that specifies a protocol is:

"protocol=http://proxy_name"

where protocol is either http or https and proxy_name is the name of the proxy server. For example, the string, "http=http://http_proxy_name:80", specifies that the protocol is HTTP, the name of the proxy server is http_proxy_name, and the port number for this server is 80. An example of a proxy listing that specifies the HTTPS protocol is "https=http://https_proxy_name".

If the proxy server uses the default port number for the protocol, the port number can be omitted.

If a proxy name is listed by itself, the proxycfg.exe utility uses that proxy as the default proxy for any protocols that do not have a proxy specified. For example, the listing, "http=http://http_proxy other_proxy", specifies to use the http_proxy server for any HTTP operations and the other_proxy server for any HTTPS operations.
optional-bypass-list This list contains host names or IP addresses that are locally known.

This list can contain wildcards, "*", that cause the application to bypass the proxy server for addresses that fit the specified pattern. For example, both "*.microsoft.com" or "*.org" are acceptable wildcard patterns. Wildcard characters must be the left-most characters in the list, so "myserver.*" is not supported.

To list multiple addresses and host names, separate them with blank spaces or semicolons in the proxy bypass string. If the "<local>" macro is specified, the function bypasses any host name that does not contain a period.

Examples

The following is the most common command used with the proxycfg.exe utility. This command specifies to use the proxy server named "itgproxy" to access both HTTP and HTTPS servers, and also bypass any host names that do not contain a period. In this case, the -d option has no effect.

proxycfg -d -p itgproxy "<local>"

Compare the previous command to the following command which specifies to use the server named "itgproxy" to access both HTTP and HTTPS servers, and not to bypass any servers.

proxycfg -p itgproxy

The following is an example of a more complex command used by the proxycfg.exe utility. This command specifies to use the server named "http_proxy" to access HTTP servers and the server named "https_proxy" to access HTTPS servers. This command also specifies that local intranet sites (for example, host names that do not contain a period) and any site in the "*.microsoft.com" domain bypass the proxy.

proxycfg -p "http=http_proxy https=https_proxy" "<local>;*.microsoft.com"

See Also

IServerXMLHTTPRequest/ServerXMLHTTP Members

Applies To: IServerXMLHTTPRequest/ServerXMLHTTP


IServerXMLHTTPRequest/ServerXMLHTTP Members

[Visual Basic, Script]

The following tables show the properties, methods, and events.

[C/C++]

The following tables show the properties, methods, and events.

This interface inherits from IXMLHTTPRequest.

Properties

onreadystatechange | Specifies the event handler to be invoked when the readyState property changes. Read/write.
responseBody | Represents the response entity body as an array of unsigned bytes. Read-only.
readyState | Represents the state of the request. Read-only.
responseStream | Represents the response entity body as an IStream. Read-only.
responseText | Represents the response entity body as a string. Read-only.
responseXML | Represents the response entity body as parsed by the Microsoft® XML Parser (MSXML). Read-only.
status | Represents the HTTP status code returned by a request. Read-only.
statusText | Represents the HTTP response line status. Read-only.

Methods

abort | Cancels the current HTTP request.
getAllResponseHeaders | Retrieves the values of all the HTTP headers.
getOption | Returns the value of one of the following options: SXH_OPTION_URL_CODEPAGE SXH_OPTION_ESCAPE_PERCENT_IN_URL SXH_OPTION_IGNORE_SERVER_SSL_CERT_ERROR_FLAGS SXH_OPTION_SELECT_CLIENT_SSL_CERT
getResponseHeader | Retrieves the value of an HTTP header from the response body.
open | Initializes a request and specifies the method, URL, and authentication information for the request.
send | Sends an HTTP request to the server and receives a response.
setOption | Sets one of the following options: SXH_OPTION_URL_CODEPAGE SXH_OPTION_ESCAPE_PERCENT_IN_URL SXH_OPTION_IGNORE_SERVER_SSL_CERT_ERROR_FLAGS SXH_OPTION_SELECT_CLIENT_SSL_CERT
setTimeouts | Specifies timeout settings for resolving the domain name, establishing the connection to the server, sending the data, and receiving the response.
setRequestHeader | Specifies the name of an HTTP header.
waitForResponse | Allows the requesting server to suspend execution while waiting for an asynchronous send operation to complete.

Events

None.


XML DOM Properties

This section includes the following topics.

  • async Property
  • attributes Property
  • baseName Property
  • childNodes Property
  • context Property
  • data Property (IXMLDOMCharacterData)
  • data Property (IXMLDOMProcessingInstruction)
  • dataType Property
  • definition Property
  • doctype Property
  • documentElement Property
  • entities Property
  • errorCode Property
  • expr Property
  • filepos Property
  • firstChild Property
  • implementation Property
  • input Property
  • lastChild Property
  • length Property (IXMLDOMCharacterData)
  • length Property (IXMLDOMNamedNodeMap)
  • length Property (IXMLDOMNodeList)
  • length Property (XMLSchemaCache/IXMLSchemaCollection)
  • line Property
  • linepos Property
  • name Property (IXMLDOMAttribute)
  • name Property (IXMLDOMDocumentType)
  • namespaces Property
  • namespaceURI Property (IXMLDOMNode)
  • namespaceURI Property (XMLSchemaCache/IXMLDOMSchemaCollection)
  • nextSibling Property
  • nodeName Property
  • nodeType Property
  • nodeTypedValue Property
  • nodeTypeString Property
  • nodeValue Property
  • notationName Property
  • notations Property
  • ondataavailable Property
  • onreadystatechange Property (DOMDocument)
  • onreadystatechange Property (IXMLHTTPRequest)
  • onreadystatechange Property (ServerXMLHTTP/IServerXMLHTTPRequest)
  • ontransformnode Property
  • output Property
  • ownerDocument Property
  • ownerTemplate Property
  • parentNode Property
  • parsed Property
  • parseError Property
  • prefix Property
  • preserveWhiteSpace Property
  • 9previousSibling Property
  • publicId Property (IXMLDOMEntity)
  • publicId Property (IXMLDOMNotation)
  • readyState Property (DOMDocument)
  • readyState Property (IXMLHTTPRequest)
  • readyState Property (IXSLProcessor)
  • readyState Property (ServerXMLHTTP/IServerHTTPRequest)
  • reason Property
  • resolveExternals Property
  • responseBody Property (IXMLHTTPRequest)
  • responseBody Property (ServerXMLHTTP/IServerXMLHTTPRequest)
  • responseStream Property (IXMLHttpRequest)
  • responseStream Property (ServerXMLHTTP/IServerXMLHTTPRequest)
  • responseText Property (IXMLHTTPRequest)
  • responseText Property (ServerXMLHTTP/IServerXMLHTTPRequest)
  • responseXML Property (IXMLHTTPRequest)
  • responseXML Property (ServerXMLHTTP/IServerXMLHTTPRequest)
  • schemas Property
  • specified Property
  • srcText Property
  • startMode Property
  • startModeURI Property
  • status Property (IXMLHTTPRequest)
  • status Property (ServerXMLHTTP/IServerXMLHTTPRequest)
  • statusText Property (IXMLHTTPRequest)
  • statusText Property (ServerXMLHTTP/IServerXMLHTTPRequest)
  • stylesheet Property (IXSLProcessor)
  • stylesheet Property (IXSLTemplate)
  • systemId Property (IXMLDOMEntity)
  • systemId Property (IXMLDOMNotation)
  • tagName Property
  • target Property
  • text Property
  • url Property (DOMDocument)
  • url Property (IXMLDOMParseError)
  • validateOnParse Property
  • value Property
  • xml Property


async Property

Specifies if asynchronous download is permitted.

[Script]

Script Syntax

boolValue = oXMLDOMDocument.async;
objXMLDOMDocument.async = boolValue;

Example

The following example sets the async property of a DOMDocument object to False before loading sample.xml.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
alert(xmlDoc.xml);
[Visual Basic]

Visual Basic Syntax

boolValue = oXMLDOMDocument.async
objXMLDOMDocument.async = boolValue

Example

The following example sets the async property of a DOMDocument object to False before loading sample.xml.

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.async = False
xmlDoc.Load ("books.xml")
MsgBox xmlDoc.xml
[C/C++]

C/C++ Syntax

HRESULT get_async(
    VARIANT_BOOL *isAsync);
HRESULT put_async(
    VARIANT_BOOL isAsync);

Parameters

isAsync [out][in]
True if asynchronous download is permitted; False if not.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG (for get_async only)
The value returned if isAsync is Null.

Remarks

Boolean. The property is read/write. Returns True if asynchronous download is permitted; False if not. Default is True.

When set to True, the load method returns control to the caller before the download is finished. You can then use the readyState property to check the status of the download. You can also attach an onreadystatechange handler or connect to the onreadystatechange event to be notified when the ready state changes so that you know when the download is complete.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

onreadystatechange Property | onreadystatechange Event | readyState Property

Applies to: DOMDocument


attributes Property

Contains the list of attributes for this node.

[Script]

Script Syntax

var objXMLDOMNamedNodeMap = oXMLDOMNode.attributes;

Example

The following creates an IXMLDOMNamedNodeMap object from a document's attributes property, and then displays the number of nodes in the object.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var oNamedNodeMap;
xmlDoc.async = false;
xmlDoc.load("books.xml");
oNamedNodeMap = xmlDoc.documentElement.firstChild.attributes;
alert(oNamedNodeMap.length);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNamedNodeMap = oXMLDOMNode.attributes

Example

The following creates an IXMLDOMNamedNodeMap object from a document's attributes property, and then displays the number of nodes in the object.

Dim xmlDoc As New Msxml2.DOMDocument
Dim oNamedNodeMap As IXMLDOMNamedNodeMap
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set oNamedNodeMap = xmlDoc.documentElement.firstChild.Attributes
MsgBox oNamedNodeMap.length
[C/C++]

C/C++ Syntax

HRESULT get_attributes(
    IXMLDOMNamedNodeMap **attributeMap);

Parameters

attributeMap [out, retval]
An IXMLDOMNamedNodeMap returned for nodes that can return attributes (Element, Entity, and Notation nodes). Returns Null for all other node types. For the valid node types, the NamedNodeMap is always returned; when there are no attributes on the element, the list length is set to zero.

C/C++ Return Values

S_OK
Success. Returns a nonnull pointer value.
S_FALSE
The value returned if the node type does not allow attributes.
E_INVALIDARG
The value returned if attributeMap is Null.

Remarks

The property is read-only. Returns IXMLDOMNamedNodeMap for nodes that can return attributes (Element, Entity, and Notation nodes). Returns Null for all other node types. For the valid node types, the NamedNodeMap is always returned; when there are no attributes on the element, the list length is set to 0.

This value depends on the value of the nodeType property.

NODE_ATTRIBUTE NODE_CDATA_SECTION NODE_COMMENT NODE_DOCUMENT NODE_DOCUMENT_FRAGMENT NODE_ENTITY_REFERENCE NODE_TEXT | Always returns Null.
NODE_ELEMENT | Returns IXMLDOMNamedNodeMap that contains a list of nodes corresponding to the attributes of the element.
NODE_PROCESSING_INSTRUCTION | Returns null for all processing instructions except the XML declaration, for example, <?xml version="1.0" encoding="windows-1252" standalone="yes" ?> For the XML declaration, the version, encoding, and standalone specifications can be accessed as attributes from the corresponding node.
NODE_DOCUMENT_TYPE | Values specified in the <!DOCTYPE ...> can be accessed as attributes from the node corresponding to the document type declaration. The names are "SYSTEM" and "PUBLIC". They are uppercase.
NODE_ENTITY NODE_NOTATION | Returns IXMLDOMNamedNodeMap that exposes the PUBLIC ID, SYSTEM ID, and NDATA as attributes.

See Also

IXMLDOMNamedNodeMap | nodeType Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


baseName Property

Returns the base name for the name qualified with the namespace.

[Script]

Script Syntax

strValue = oXMLDOMNode.baseName;

Example

The following script example assigns the value of a node's baseName property to a string, and then displays it.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var MyStr;
xmlDoc.async = false;
xmlDoc.load("books.xml");
MyStr = xmlDoc.documentElement.childNodes.item(1).baseName;
alert(MyStr);
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMNode.baseName

Example

The following Microsoft® Visual Basic® example assigns the value of a node's baseName property to a string, and then displays it.

Dim xmlDoc As New Msxml2.DOMDocument
Dim MyStr As String
xmlDoc.async = False
xmlDoc.Load ("books.xml")
MyStr = xmlDoc.documentElement.childNodes.Item(1).baseName
MsgBox MyStr
[C/C++]

C/C++ Syntax

HRESULT get_baseName(
    BSTR *nameString);

Parameters

nameString [out, retval]
The right-hand side of a namespace qualified name. For example, it returns yyy for the element <xxx:yyy>. It always returns a nonempty string.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned when there is no base name.
E_INVALIDARG
The value returned if nameString is Null.

Remarks

String. The property is read-only. It returns the right-hand side of a namespace-qualified name. For example, it returns "yyy" for the element <xxx:yyy>. It always returns a nonempty string.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


childNodes Property

Contains a node list containing the children nodes.

[Script]

Script Syntax

objXMLDOMNodeList = oXMLDOMNode.childNodes;

Example

The following script example uses the childNodes property (collection) to return an IXMLDOMNodeList, and then iterates through the collection, displaying the value of each item's xml property.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var oNodeList;
var Item;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
oNodeList = root.childNodes;
for (var i=0; i<oNodeList.length; i++) {
   Item = oNodeList.item(i);
  alert(Item.xml);
}
[Visual Basic]

Visual Basic Syntax

objXMLDOMNodeList = oXMLDOMNode.childNodes

Example

The following Microsoft® Visual Basic® example uses the childNodes property (collection) to return an IXMLDOMNodeList, and then iterates through the collection, displaying the value of each item's xml property.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim oNodeList As IXMLDOMNodeList
Dim Item As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
Set oNodeList = root.childNodes
For Each Item In oNodeList
  MsgBox Item.xml
Next
[C/C++]

C/C++ Syntax

HRESULT get_childNodes(
    IXMLDOMNodeList **childList);

Parameters

childList [out, retval]
A list of children in the current node.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if childList is Null.

Remarks

The property (collection) is read-only. IXMLDOMNodeList is returned even if there are no children of the node. In such a case, the length of the list will be set to 0. For information about valid child node types for each node, see XML DOM Enumerated Constants.

This value depends on the value of the nodeType property.

NODE_ATTRIBUTE, NODE_DOCUMENT, NODE_DOCUMENT_FRAGMENT, NODE_ELEMENT, NODE_ENTITY, NODE_ENTITY_REFERENCE | Returns an IXMLDOMNodeList that contains a list of all child nodes for the specified node.
NODE_CDATA_SECTION, NODE_COMMENT, NODE_NOTATION, NODE_PROCESSING_INSTRUCTION, NODE_TEXT | Returns an IXMLDOMNodeList with a length of 0. These node types cannot have children.
NODE_DOCUMENT_TYPE | Returns an IXMLDOMNodeList that contains a list of all child nodes for the IXMLDOMDocumentType node. The node list for the document type node can contain entities and notations.

See Also

IXMLDOMNodeList | nodeType Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


context Property

Gets the node (subtree) that is applied to the selection.

[Script]

Script Syntax

var objXMLDOMNode = objXMLDOMSelection.context;
objXMLDOMSelection.context = objXMLDOMNode;

Example

The following script example shows what is contained in the context of a selection after a query is executed. It also shows that the selection is reset when this property is changed.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var selection;
xmlDoc.loadXML("<Customer>Microsoft</Customer>");
xmlDoc.setProperty("SelectionLanguage", "XPath");
selection = xmlDoc.selectNodes("//Customer");
alert(selection.context.xml);

The selection.context.xml contains "<Customer>Microsoft</Customer>", selection.length = 1.

xmlDoc.loadXML("<new>none</new>");
alert(selection.context.xml);

The selection.context.xml contains "<new>none</new>", selection.length = 0.

[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = objXMLDOMSelection.context
objXMLDOMSelection.context = objXMLDOMNode

Example

The following Microsoft® Visual Basic® example shows what is contained in the context of a selection after a query is executed. It also shows that the selected set is reset when this property is changed.

Dim xmlDoc As New Msxml2.DOMDocument
Dim selection As Msxml2.IXMLDOMSelection

xmlDoc.loadXML ("<Customer>Microsoft</Customer>")
xmlDoc.setProperty "SelectionLanguage", "XPath"
Set selection = xmlDoc.selectNodes("//Customer")
MsgBox selection.context.xml

The selection.context.xml contains "<Customer>Microsoft</Customer>", selection.length = 1.

xmlDoc.loadXML ("<new>none</new>")
MsgBox selection.context.xml

The selection.context.xml contains "<new>none</new>", selection.length = 0.

[C/C++]

C/C++ Syntax

HRESULT get_context(IXMLDOMNode ** ppNode);
HRESULT putref_context(IXMLDOMNode * pNode);

Parameters

ppNode [out, retval]
The subtree to apply the pattern to.
pNode [in]
The subtree to apply the pattern to.

C/C++ Return Values

S_OK
The value returned if the method is successful.
S_FALSE (for get_context only)
The value returned if the context is invalid.
E_INVALIDARG (for get_context only)
The value returned if the input argument is Null.
E_FAIL (for putref_context only)
The value returned if a node with a different threading model is provided.

Example

The following C/C++ example shows what is contained in the context property after selectNodes is executed.

#import "msxml3.dll"
using namespace MSXML2;

#define CHECK_AND_RELEASE(pInterface)  \
if(pInterface) \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

#define RELEASE(pInterface)  \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

BOOL DOMSelectionContextDemo()
{
   BOOL bResult = FALSE;
   short sResult = FALSE;
   IXMLDOMSelection *pIXMLDOMSelection=NULL;
   IXMLDOMNode *pIXMLDOMNode=NULL;
   IXMLDOMDocument2 *pIXMLDOMDocument2=NULL;
   HRESULT hr;
   BSTR bstrValue;

   try
   {
      hr=CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_SERVER,
         IID_IXMLDOMDocument2, (LPVOID*)(&pIXMLDOMDocument2));
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXMLDOMDocument2)
      {
         hr=pIXMLDOMDocument2->put_async(VARIANT_FALSE);
         if(SUCCEEDED(hr))
         {
            hr=pIXMLDOMDocument2->load(_variant_t(
               _T("d:\\inetpub\\wwwroot\\samplexml.xml")), &sResult);
            if(SUCCEEDED(hr) && (sResult==VARIANT_TRUE))
            {
               hr=pIXMLDOMDocument2->selectNodes(
               _T("*/BOOK[TITLE='Cosmos']"),
               (IXMLDOMNodeList**)&pIXMLDOMSelection);
               if(SUCCEEDED(hr))
               {
                  if(SUCCEEDED(hr) && pIXMLDOMSelection)
                  {
                     hr=pIXMLDOMSelection->get_context(&pIXMLDOMNode);
                     if(SUCCEEDED(hr) && pIXMLDOMNode)
                     {
                        hr=pIXMLDOMNode->get_xml(&bstrValue);
                        if(SUCCEEDED(hr))
                           ::MessageBox(NULL, bstrValue, _T("Current
                              Selection Context"), MB_OK);
                        bResult=TRUE;
                        RELEASE(pIXMLDOMNode);
                     }
                     RELEASE(pIXMLDOMSelection);
                  }
               }
            }
         }
         RELEASE(pIXMLDOMDocument2);
      }
   }
   catch(...)
   {
      CHECK_AND_RELEASE(pIXMLDOMNode);
      CHECK_AND_RELEASE(pIXMLDOMSelection);
      CHECK_AND_RELEASE(pIXMLDOMDocument2);
      DisplayErrorToUser();
   }
   return bResult;
}

Data File: d:\\inetpub\\wwwroot\\samplexml.xml

<?xml version='1.0'?>
<COLLECTION xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
   <BOOK>
      <TITLE>Cosmos</TITLE>
      <AUTHOR>Carl Sagan</AUTHOR>
      <PUBLISHER>Ballantine Books</PUBLISHER>
   </BOOK>
   <BOOK>
      <TITLE>Catwings</TITLE>
      <AUTHOR>Ursula K. Le Guin</AUTHOR>
      <PUBLISHER>Scholastic</PUBLISHER>
   </BOOK>
</COLLECTION>

Output (in a message box)

<?xml version='1.0'?>
<COLLECTION xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
   <BOOK>
      <TITLE>Cosmos</TITLE>
      <AUTHOR>Carl Sagan</AUTHOR>
      <PUBLISHER>Ballantine Books</PUBLISHER>
   </BOOK>
   <BOOK>
      <TITLE>Catwings</TITLE>
      <AUTHOR>Ursula K. Le Guin</AUTHOR>
      <PUBLISHER>Scholastic</PUBLISHER>
   </BOOK>
</COLLECTION>

Remarks

Because the selectNodes method can be called on any node type, context can also be assigned any node type. A node from a document different from the one that originally created IXMLDOMSelection can also be specified as long as it has the same threading model. Calling context also resets the state of the node list so that nextNode starts over.

See Also

Applies to: IXMLDOMSelection


data Property (IXMLDOMCharacterData)

Stores the node data depending on the node type.

[Script]

Script Syntax

strValue = oXMLDOMCharacterData.data;
objXMLDOMCharacterData.data = strValue;

Example

The following script example walks the document tree and checks for comment node types. If one is found, it displays its contents with the data property.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var comment;
var root;
xmlDoc.async = false;
xmlDoc.loadXML("<root><!-- Hello --></root>");
root = xmlDoc.documentElement;
for (var i=0; i<root.childNodes.length; i++) {
  if (root.childNodes.item(i).nodeType == 8) {
    comment = root.childNodes.item(i);
    alert(comment.data);
  }
}
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMCharacterData.data
objXMLDOMCharacterData.data = strValue

Example

The following Microsoft® Visual Basic® example walks the document tree and checks for comment node types. If one is found, it displays its contents with the data property.

Dim xmlDoc As New Msxml2.DOMDocument
Dim comment As IXMLDOMComment
Dim root As IXMLDOMElement
xmlDoc.async = False
xmlDoc.loadXML ("<root><!-- Hello --></root>")
Set root = xmlDoc.documentElement
For i = 0 To (root.childNodes.length - 1)
  If root.childNodes.Item(i).nodeType = NODE_COMMENT Then
    Set comment = root.childNodes.Item(i)
    MsgBox comment.Data
  End If
Next
[C/C++]

C/C++ Syntax

HRESULT get_data(
    BSTR *data);
HRESULT put_data(
    BSTR data);

Parameters

data [out, retval][in]
The same value as the nodeValue for this node.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE (for get_data only)
The value returned if there is no character data node.
E_INVALIDARG (for get_data only)
The value returned if data is Null.
E_FAIL (for put_data only)
The value returned if an error occurs.

Remarks

String. The property is read/write. It contains the same value as the nodeValue for this node. The meaning of the value depends on the nodeType property of the IXMLDOMNode, as follows.

NODE_CDATA_SECTION | A string representing the text stored in the CDATA section.
NODE_COMMENT | The content of the comment, exclusive of the comment start and end sequence.
NODE_TEXT | A string representing the text stored in the text node.

See Also

IXMLDOMNode | nodeType Property | nodeValue Property

Applies to: IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | IXMLDOMText


data Property (IXMLDOMProcessingInstruction)

Retrieves and sets the content of the processing instruction, excluding the target.

[Script]

Script Syntax

strValue = oXMLDOMProcessingInstruction.data;
objXMLDOMProcessingInstruction.data = strValue;

Example

The following script example iterates through the document's child nodes. If it finds a node of type NODE_PROCESSING_INSTRUCTION (7), it displays the node's data.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var pi;
xmlDoc.load("books.xml");
for (var i=0; i<xmlDoc.childNodes.length; i++) {
  if (xmlDoc.childNodes.item(i).nodeType == 7) {
    pi = xmlDoc.childNodes.item(i);
    alert(pi.data);
  }
}
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMProcessingInstruction.data
objXMLDOMProcessingInstruction.data = strValue

Example

The following Microsoft® Visual Basic® example iterates through the document's child nodes. If it finds a node of type NODE_PROCESSING_INSTRUCTION (7), it displays the node's data.

Dim xmlDoc As New Msxml2.DOMDocument
Dim pi As IXMLDOMProcessingInstruction
xmlDoc.Load ("books.xml")
For i = 0 To (xmlDoc.childNodes.length - 1)
  If xmlDoc.childNodes.Item(i).nodeType = NODE_PROCESSING_INSTRUCTION Then
    Set pi = xmlDoc.childNodes.Item(i)
    MsgBox pi.Data
  End If
Next
[C/C++]

C/C++ Syntax

HRESULT get_data(
    BSTR *value);
HRESULT put_data(
    BSTR value);

Parameters

value [out, retval][in]
The content of the processing instruction for this target. The data has the same value as the nodeValue property.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

String. This property is read/write. The data has the same value as the nodeValue property.

See Also

nodeValue Property

Applies to: IXMLDOMProcessingInstruction


dataType Property

Specifies the data type for this node.

[Script]

Script Syntax

objValue = oXMLDOMNode.dataType;
objXMLDOMNode.dataType = objValue;

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.loadXML("<root/>");
var root = xmlDoc.documentElement;
root.dataType = "int";
root.nodeTypedValue = 5;
alert(xmlDoc.xml);
[Visual Basic]

Visual Basic Syntax

objValue = oXMLDOMNode.dataType
objXMLDOMNode.dataType = objValue

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
xmlDoc.async = False
xmlDoc.loadXML "<root/>"
Set root = xmlDoc.documentElement
root.dataType = "int"
root.nodeTypedValue = 5
MsgBox xmlDoc.xml
[C/C++]

C/C++ Syntax

HRESULT get_dataType(
    VARIANT *dataTypeName);
HRESULT put_dataType(
    BSTR dataTypeName);

Parameters

dataTypeName [out, retval][in]
The VARIANT can be a BSTR that contains the data type name, or VT_NULL if no data type is defined.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE (for get_dataType only)
The value returned if the node is not typed.
E_INVALIDARG (for get_dataType only)
The value returned if dataTypeName is Null.
E_FAIL (for put_dataType only)
The value returned if an error occurs.

Remarks

The property is read/write. The VARIANT can be a BSTR that contains the data type name, or VT_NULL if no data type is defined.

This value depends on the value of the nodeType property of the IXMLDOMNode.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

NODE_ATTRIBUTE | Contains the string representation of the data type specifier included in the schema, or Null if no data type is specified.
NODE_CDATA_SECTION, NODE_COMMENT, NODE_DOCUMENT, NODE_DOCUMENT_FRAGMENT, NODE_DOCUMENT_TYPE, NODE_ENTITY, NODE_NOTATION, NODE_PROCESSING_INSTRUCTION, NODE_TEXT | Contains the constant string value "string." These node types do not have data types, so the dataType property cannot be set for these node types. Attempts to set this property are ignored.
NODE_ELEMENT | Contains the string representation of the data type specifier included on the instance of the element or in the schema, or Null if no data type is specified.
NODE_ENTITY_REFERENCE | Contains the string representation of the data type specifier for the referenced entity. This is limited to entities with a single data type on the root level element of the subtree corresponding to the entity. Contains Null if no data type is specified. It is not possible to set the data type of an entity reference. The data type must be set directly on the referenced element. Attempts to set the value of the dataType property are ignored.

See Also

nodeType Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


definition Property

Returns the definition of the node in the document type definition (DTD) or schema.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNode.definition;
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNode.definition
[C/C++]

C/C++ Syntax

HRESULT get_definition(
    IXMLDOMNode **definitionNode);

Parameters

definitionNode [out, retval]
The node that contains the definition for the entity referenced.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned when no definition is found.
E_INVALIDARG
The value returned if definitionNode is Null.

Example

The following C/C++ example shows the retrieval of the definition property from an IXMLDOMElement.

#import "msxml3.dll"
using namespace MSXML2;

#define CHECK_AND_RELEASE(pInterface)  \
if(pInterface) \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

#define RELEASE(pInterface)  \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

BOOL DOMNodeGetDefinition()
{
   BOOL bResult = FALSE;
   BSTR bstrValue;
   IXMLDOMElement *pIXMLDOMElement = NULL;
   IXMLDOMNode *pIXMLDOMNode = NULL;
   IXMLDOMDocument2 *pIXMLDOMDocument = NULL;
   HRESULT hr;

   try
   {
      // Create the document and initialize pIXMLDOMDocument.
      // Load the document (sample.xml).
      // Get the documents root.
      hr = pIXMLDOMDocument->get_documentElement(&pIXMLDOMElement);
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXMLDOMElement)
      {
         hr = pIXMLDOMElement->get_definition(&pIXMLDOMNode);
         if(SUCCEEDED(hr) && pIXMLDOMNode)
         {
            hr = pIXMLDOMNode->get_xml(&bstrValue);
            if(SUCCEEDED(hr) && bstrValue)
            {
               ::MessageBox(NULL, bstrValue, _T("Definition"), MB_OK);
               ::SysFreeString(bstrValue);
               bResult = TRUE;
            }
            RELEASE(pIXMLDOMNode);
         }
         RELEASE(pIXMLDOMElement);
      }
   }
   catch(...)
   {
      if(bstrValue)
         ::SysFreeString(bstrValue);
      CHECK_AND_RELEASE(pIXMLDOMNode);
      CHECK_AND_RELEASE(pIXMLDOMElement);
      // Release the DOMDocument.
      DisplayErrorToUser();
   }
   // Release the document when finished with it.
   return bResult;
}

Sample.xml

<?xml version="1.0"?>
<SomeDoc xmlns="x-schema:collschema.xml">
   <SomeElement Id="first1">
   </SomeElement>
</SomeDoc>

collschema.xml

<?xml version='1.0'?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
       xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <AttributeType name='Id' dt:type="id"/>
   <ElementType name='SomeElement' content="mixed" model="open">
      <attribute type='Id'/>
   </ElementType>

   <ElementType name='SomeDoc' content="mixed" model="open">
      <attribute type='Id'/>
      <element type='SomeElement' minOccurs='1' maxOccurs='*'/>
   </ElementType>
</Schema>

Output (in a message box)

<ElementType name='SomeDoc' content="mixed" model="open">
   <attribute type='Id'/>
   <element type='SomeElement' minOccurs='1' maxOccurs='*'/>
</ElementType>

Remarks

The property is read-only. Returns the node that contains the definition for the entity referenced.

The definition property is not supported when using inline schemas. This behavior is by design because the node being referenced can be deleted or modified after the document is loaded, yielding unpredictable results.

This value depends on the value of the nodeType property.

NODE_ENTITY_REFERENCE | Returns the node for the entity referenced; that is, the ENTITY element that was defined for a given ENTITYREF. Given the ENTITYREF &x;, for example, the definition property returns the node in the DOCTYPE node's entity collection that defines the corresponding ENTITY: <!ENTITY x "y">.
NODE_ENTITY | For unparsed entities, returns the NOTATION definition from the DOCTYPE node's notation collection. For example, given the ENTITY <!ENTITY networth SYSTEM "networth.xls" NDATA XLS>, the definition property returns the node corresponding to the notation <!NOTATION XLS PUBLIC "http://www.microsoft.com/office/excel/">. For parsed entities, returns Null.
NODE_ATTRIBUTE | Returns the XML-Data Schema AttributeType for a given ATTRIBUTE node. For example, the definition property for the attribute myAttribute="123" returns the node corresponding to the element <AttributeType name= "myAttribute"> in the schema. Returns Null when a DTD is used or when no schema is present.
NODE_ELEMENT | Returns the XML-Data Schema ElementType for a given ELEMENT node. For example, given the element <myelement>, the definition property returns the node <ElementType name="myelement"> in the specified external schema. Returns Null when a DTD is used or when no schema is present.
NODE_CDATA_SECTION, NODE_COMMENT, NODE_DOCUMENT, NODE_DOCUMENT_FRAGMENT, NODE_DOCUMENT_TYPE, NODE_NOTATION, NODE_PROCESSING_INSTRUCTION, NODE_TEXT | Returns Null.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

nodeType Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


doctype Property

Contains the document type node that specifies the document type definition (DTD) for this document.

[Script]

Script Syntax

var objXMLDOMDocumentType = oXMLDOMDocument.doctype;

Example

The following script example creates an IXMLDOMDocumentType object, and then displays the name property of the object.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var MyDocType;
xmlDoc.async = false;
xmlDoc.load("books.xml");
MyDocType = xmlDoc.doctype;
if (MyDocType != null) {
   alert(MyDocType.name);
}
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMDocumentType = oXMLDOMDocument.doctype

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMDocumentType object, and then displays the name property of the object.

Dim xmlDoc As New Msxml2.DOMDocument
Dim MyDocType As IXMLDOMDocumentType
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set MyDocType = xmlDoc.doctype
If Not MyDocType Is Nothing Then
    MsgBox MyDocType.Name
End If
[C/C++]

C/C++ Syntax

HRESULT get_doctype(
    IXMLDOMDocumentType **documentType);

Parameters

documentType [out, retval]
For XML, the address of the node of type NODE_DOCUMENT_TYPE that specifies the DTD. Returns Null for for HTML documents and XML documents without a DTD.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned when there is no document type node.
E_INVALIDARG
The value returned if documentType is Null.

Remarks

The property is read-only. For XML, it points to the node of type NODE_DOCUMENT_TYPE that specifies the DTD. It returns Null for HTML documents and XML documents without a DTD.

An XML document can contain a document type declaration before the first element in the document. It starts with the tag <!DOCTYPE> and can specify an external DTD.

See Also

Applies to: DOMDocument |IXMLDOMDocumentType


documentElement Property

Contains the root element of the document.

[Script]

Script Syntax

var objXMLDOMElement = oXMLDOMDocument.documentElement;
objXMLDOMDocument.documentElement = objXMLDOMElement;

Example

The following script example creates an IXMLDOMElement object and sets it to the root element of the document with the documentElement property. It then walks the document tree.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
for (var i=0; i<root.childNodes.length; i++) {
  alert(root.childNodes.item(i).childNodes.item(0).text);
}
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMElement = oXMLDOMDocument.documentElement
Set objXMLDOMDocument.documentElement = objXMLDOMElement

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMElement object and sets it to the root element of the document with the documentElement property. It then walks the document tree.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
For i = 0 To (root.childNodes.length - 1)
  MsgBox root.childNodes.Item(i).childNodes.Item(0).Text
Next
[C/C++]

C/C++ Syntax

HRESULT get_documentElement(
    IXMLDOMElement** DOMElement);
HRESULT putref_documentElement(
    IXMLDOMElement* DOMElement);

Parameters

DOMElement [out, retval][in]
The IXMLDOMElement object that represents the single element representing the root of the XML document tree. Returns Null if no root exists.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE (for get_documentElement only)
The value returned if there is no document element.
E_INVALIDARG (for get_documentElement only)
The value returned if DOMElement is Null.

Remarks

The property is read/write. It returns an IXMLDOMElement that represents the single element that represents the root of the XML document tree. It returns Null if no root exists.

When setting the documentElement property, the specified element node is inserted into the child list of the document after any document type node. To precisely place the node within the children of the document, call the insertBefore method of the IXMLDOMNode.

The parentNode property is reset to the document node as a result of this operation.

See Also

insertBefore Method | IXMLDOMElement | IXMLDOMNode | parentNode Property

Applies to: DOMDocument


entities Property

Contains a list of the entities declared in the DOCTYPE declaration.

[Script]

Script Syntax

var objXMLDOMNamedNodeMap = oXMLDOMDocumentType.entities;
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNamedNodeMap = oXMLDOMDocumentType.entities
[C/C++]

C/C++ Syntax

HRESULT get_entities(
    IXMLDOMNamedNodeMap **entityMap);

Parameters

entityMap [out, retval]
A list of the general entities, both external and internal, that are present in this document.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if entityMap is Null.

Example

IXMLDOMEntity *GetRootEntity()
{
   HRESULT hr;
   IXMLDOMNamedNodeMap *pIXMLDOMNamedNodeMapEntities = NULL;
   IXMLDOMEntity *pIXMLDOMEntity = NULL;
   IXMLDOMNode *pIXMLDOMNode = NULL;
   IXMLDOMDocument *pIXMLDOMDocument = NULL;
   IXMLDOMDocumentType *pIXMLDOMDocumentType = NULL;

   try
   {
      // Create an instance of DOMDocument and initialize
      // pIXMLDOMDocument.
      // Load/create an XML fragment.
      hr = pIXMLDOMDocument->get_doctype(&pIXMLDOMDocumentType);
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXMLDOMDocumentType)
      {
         hr = pIXMLDOMDocumentType->get_entities
                        (&pIXMLDOMNamedNodeMapEntities);
         if(SUCCEEDED(hr) && pIXMLDOMNamedNodeMapEntities)
         {
            hr = pIXMLDOMNamedNodeMapEntities->nextNode(&pIXMLDOMNode);
            if(SUCCEEDED(hr) && pIXMLDOMNode)
            {
               hr = pIXMLDOMNode->QueryInterface(IID_IXMLDOMEntity,
                     (void**)&pIXMLDOMEntity );
               SUCCEEDED(hr) ? 0 : throw hr;
               pIXMLDOMNode->Release();
               pIXMLDOMNode = NULL;
            }
            pIXMLDOMNamedNodeMapEntities->Release();
         }
         pIXMLDOMDocumentType->Release();
      }
   }
   catch(...)
   {
      if(pIXMLDOMNode)
         pIXMLDOMNode->Release();
      DisplayErrorToUser();
   }

   // Release pIXMLDOMEntity when finished using it.
   return pIXMLDOMEntity;
}

Remarks

The property is read-only. In the following DOCTYPE declaration, for example, the node list in this property contains the entities "bat" and "bar".

<!DOCTYPE ex SYSTEM "ex.dtd" [
  <!ENTITY bat "bat">
  <!ENTITY bar "bar">
]>

See Also

Applies to: IXMLDOMDocumentType


errorCode Property

Contains the error code of the last parse error.

[Script]

Script Syntax

lValue = oXMLDOMParseError.errorCode;

Example

The following script example attempts to load an XML document. If it encounters a parse error, it displays the error code.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
if (xmlDoc.parseError.errorCode != 0) {
   alert(xmlDoc.parseError.errorCode);
} else {
   alert(xmlDoc.documentElement.xml);
}
[Visual Basic]

Visual Basic Syntax

lValue = oXMLDOMParseError.errorCode

Example

The following Microsoft® Visual Basic® example attempts to load an XML document. If it encounters a parse error, it displays the error code.

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.async = False
xmlDoc.Load ("books.xml")
If xmlDoc.parseError.errorCode <> 0 Then
   MsgBox xmlDoc.parseError.errorCode
Else
  MsgBox xmlDoc.documentElement.xml
End If
[C/C++]

C/C++ Syntax

HRESULT get_errorCode(
    long *errorCode);

Parameters

errorCode [out, retval]
The error code returned in a decimal value.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned if no error occurred.

Remarks

Long integer. The property is read-only. It returns the error code in decimal.

See Also

Applies to: IXMLDOMParseError


expr Property

Gets or sets the XML Path Language (XPath) expression string.

[Script]

Script Syntax

strExpression = objXMLDOMSelection.expr;
objXMLDOMSelection.expr = strExpression;

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var selection;
xmlDoc.loadXML("<Customer><Name>Microsoft</Name></Customer>");
xmlDoc.setProperty("SelectionLanguage", "XPath");
selection = xmlDoc.selectNodes("Customer/Name");
alert(selection.expr + " -- " + selection.item(0).xml);

This displays "Customer/Name -- <Name> Microsoft</Name>".

selection.expr = "/Customer";

The selection is immediately refreshed with a list corresponding to the new expression.

alert(selection.expr + " -- " + selection.item(0).xml);

This displays "/Customer -- <Customer><Name> Microsoft</Name></Customer>".

[Visual Basic]

Visual Basic Syntax

strExpression = objXMLDOMSelection.expr
objXMLDOMSelection.expr = strExpression

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim selection As Msxml2.IXMLDOMSelection

xmlDoc.loadXML ("<Customer><Name>Microsoft</Name></Customer>")
xmlDoc.setProperty "SelectionLanguage", "XPath"
Set selection = xmlDoc.selectNodes("Customer/Name")
MsgBox selection.expr + " -- " + selection.Item(0).xml

This displays "Customer/Name -- <Name> Microsoft</Name>".

selection.expr = "/Customer"

The selection is immediately refreshed with a list corresponding to the new expression.

MsgBox selection.expr + " -- " + selection.Item(0).xml

This displays "/Customer -- <Customer><Name> Microsoft</Name></Customer>".

[C/C++]

C/C++ Syntax

HRESULT get_expr(BSTR* expression);
HRESULT put_expr(BSTR expression);

Parameters

expression [out, retval][in]
The IXMLDOMSelection expression string is either XSL Pattern or XPath syntax, depending on the setting of the SelectionLanguage internal property (flag) on the IXMLDOMDocument2 interface that created this Selection object. (For more information, see IXMLDOMDocument2::setProperty.) After it is created, the IXMLDOMSelection object continues to use the expression language with which it was created.

C/C++ Return Values

S_OK
The value returned if method is successful.

E_FAIL and formatted error message through IErrorInfo if expression is invalid.

Example

The following C/C++ example shows the resetting of the selected nodes list if the expr property is changed.

#import "msxml3.dll"
using namespace MSXML2;

#define CHECK_AND_RELEASE(pInterface)  \
if(pInterface) \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

#define RELEASE(pInterface)  \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

BOOL DOMSelectionExprDemo()
{
   BOOL bResult = FALSE;
   short sResult = FALSE;
   long lvalue;
   IXMLDOMSelection *pIXMLDOMSelection=NULL;
   IXMLDOMDocument2 *pIXMLDOMDocument2=NULL;
   HRESULT hr;
   BSTR bstrValue;

   try
   {
      hr=CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_SERVER,
         IID_IXMLDOMDocument2, (LPVOID*)(&pIXMLDOMDocument2));
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXMLDOMDocument2)
      {
         hr=pIXMLDOMDocument2->put_async(VARIANT_FALSE);
         if(SUCCEEDED(hr))
         {
            hr=pIXMLDOMDocument2->load(_variant_t(
               _T("d:\\inetpub\\wwwroot\\sample.xml")), &sResult);
            if(SUCCEEDED(hr) && (sResult==VARIANT_TRUE))
            {
               hr=pIXMLDOMDocument2->selectNodes(
                  _T("*/BOOK[TITLE='Cosmos']"),
                  (IXMLDOMNodeList**)&pIXMLDOMSelection);
               if(SUCCEEDED(hr))
               {
                  if(SUCCEEDED(hr) && pIXMLDOMSelection)
                  {
                     hr = pIXMLDOMSelection->get_expr(&bstrValue);
                     if(SUCCEEDED(hr))
                     {
                        ::MessageBox(NULL, bstrValue, _T("Current
                           Expression"), MB_OK);
                        bResult=TRUE;
                        hr = pIXMLDOMSelection->get_length(&lvalue);
                        hr = pIXMLDOMSelection->put_expr(_T("*/BOOK"));
                        hr = pIXMLDOMSelection->get_length(&lvalue);
                     }
                     RELEASE(pIXMLDOMSelection);
                  }
               }
            }
         }
         RELEASE(pIXMLDOMDocument2);
      }
   }
   catch(...)
   {
      CHECK_AND_RELEASE(pIXMLDOMSelection);
      CHECK_AND_RELEASE(pIXMLDOMDocument2);
      DisplayErrorToUser();
   }
   return bResult;
}

File Name: d:\\inetpub\\wwwroot\\sample.xml

<?xml version='1.0'?>
<COLLECTION xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
   <BOOK>
      <TITLE>Cosmos</TITLE>
      <AUTHOR>Carl Sagan</AUTHOR>
      <PUBLISHER>Ballantine Books</PUBLISHER>
   </BOOK>
   <BOOK>
      <TITLE>Catwings</TITLE>
      <AUTHOR>Ursula K. Le Guin</AUTHOR>
      <PUBLISHER>Scholastic</PUBLISHER>
   </BOOK>
</COLLECTION>

Output (in a message box)

The first message box will display "1".

The second message box will display "2". When the expression changes, the nodes in the selection are recomputed using the new expression. No changes are made to the context property.

Remarks

Immediately setting a new expression resets the state of this node list to the beginning unless the expression is invalid and an error is returned, in which case it has no effect. It does not reset the context property.

See Also

Applies to: IXMLDOMSelection


filepos Property

Contains the absolute file position where the error occurred.

[Script]

Script Syntax

lValue = oXMLDOMParseError.filepos;

Example

The following script example attempts to load an XML document. If it encounters a parse error, it displays the value of the filepos property.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
if (xmlDoc.parseError.errorCode != 0) {
   alert(xmlDoc.parseError.filepos);
} else {
   alert(xmlDoc.documentElement.xml);
}
[Visual Basic]

Visual Basic Syntax

lValue = oXMLDOMParseError.filepos

Example

The following example attempts to load an XML document. If it encounters a parse error, it displays the value of the filepos property.

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.async = False
xmlDoc.Load ("books.xml")
If xmlDoc.parseError.errorCode <> 0 Then
   MsgBox xmlDoc.parseError.filepos
Else
   MsgBox xmlDoc.documentElement.xml
End If
[C/C++]

C/C++ Syntax

HRESULT get_filepos(
    long *filePosition);

Parameters

filePosition [out, retval]
The absolute file position where the error occurred.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned if no error occurred.

Remarks

Long integer. The property is read-only.

See Also

Applies to: IXMLDOMParseError


firstChild Property

Contains the first child of the node.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNode.firstChild;

Example

The following example sets currNode to the first child node of the top-level node.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var currNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
currNode = xmlDoc.documentElement.firstChild;
alert(currNode.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNode.firstChild

Example

The following example sets currNode to the first child node of the top-level node.

Dim xmlDoc As New Msxml2.DOMDocument
Dim currNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set currNode = xmlDoc.documentElement.firstChild
MsgBox currNode.xml
[C/C++]

C/C++ Syntax

HRESULT get_firstChild(
    IXMLDOMNode **firstChild);

Parameters

firstChild [out, retval]
The first child node. If there are no such children, it returns Null.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned when there are no children.
E_INVALIDARG
The value returned if firstChild is Null.

Remarks

The property is read-only. Returns the first child node. If there are no such children, returns Null.

This value depends on the value of the nodeType property.

NODE_ATTRIBUTE, NODE_DOCUMENT, NODE_DOCUMENT_FRAGMENT, NODE_DOCUMENT_TYPE, NODE_ELEMENT, NODE_ENTITY, NODE_ENTITY_REFERENCE | Returns the first child node. If there are no children, returns Null.
NODE_CDATA_SECTION, NODE_COMMENT, NODE_NOTATION, NODE_PROCESSING_INSTRUCTION, NODE_TEXT | Returns Null. These node types cannot have children.

See Also

nodeType Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment |DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


implementation Property

Contains the IXMLDOMImplementation object for the document.

[Script]

Script Syntax

var objXMLDOMImplementation = oXMLDOMDocument.implementation;

Example

The following script example creates an IXMLDOMImplementation object.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var oImplementation;
xmlDoc.async = false;
xmlDoc.load("books.xml");
oImplementation = xmlDoc.implementation;
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMImplementation = oXMLDOMDocument.implementation

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMImplementation object.

Dim xmlDoc As New Msxml2.DOMDocument
Dim oImplementation As IXMLDOMImplementation
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set oImplementation = xmlDoc.implementation
[C/C++]

C/C++ Syntax

HRESULT get_implementation(
    IXMLDOMImplementation **impl);

Parameters

impl [out, retval]
The IXMLDOMImplementation for this document.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if impl is Null.

Example

IXMLDOMDocument * pIXMLDOMDocument = NULL;
IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
VARIANT_BOOL varbFlag ;
BSTR bstrOutput = NULL;
BSTR bstrFeature = ::SysAllocString(_T("MS-DOM"));

try
{
   // Initialize pIXMLDOMDocument (create a DOMDocument).
   // Load document.
   hr = pIXMLDOMDocument->get_implementation (&pIXMLDOMImplementation);

   if(SUCCEEDED(hr) && pIXMLDOMImplementation)
   {
      pIXMLDOMImplementation->hasFeature(bstrFeature, _T("1.0"),
                  &varbFlag);
      if(varbFlag == VARIANT_TRUE )
         bstrOutput = ::SysAllocString(_T("Feature Supported"));
      else
         bstrOutput = ::SysAllocString(_T("Feature not Supported"));

      ::MessageBox(NULL, bstrOutput, bstrFeature, MB_OK);
      pIXMLDOMImplementation->Release();
      pIXMLDOMImplementation = NULL;
      ::SysFreeString(bstrOutput);
      bstrOutput = NULL;
   }
   ::SysFreeString(bstrFeature);
   bstrFeature = NULL;
}
catch(...)
{
   if(pIXMLDOMImplementation)
      pIXMLDOMImplementation->Release();
   if(bstrOutput)
      ::SysFreeString(bstrOutput);
   if(bstrFeature)
      ::SysFreeString(bstrFeature);
   DisplayErrorToUser();
}
// Release pIXMLDOMDocument when finished with it.

Remarks

The property is read-only. An XML Document Object Model (DOM) application can use objects from multiple implementations. This property provides access to IXMLDOMImplementation that handles this document.

See Also

IXMLDOMImplementation

Applies to: DOMDocument


input Property

Specifies which XML input tree to transform.

[Script]

Script Syntax

var objXMLDOMNode = objXSLProcessor.input;
objXMLDOMXSLProcessor.input = objXMLDOMNode;

Example

var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xslProc;
xslDoc.async = false;
xslDoc.load("sample2.xsl");
xslt.stylesheet = xslDoc;
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
xslProc = xslt.createProcessor();
xslProc.input = xmlDoc;
xslProc.transform();
alert(xslProc.output);

Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html"/>
    <xsl:param name="param1"/>
    <xsl:template match="/">
        Hello
    </xsl:template>
    <xsl:template match="/" mode="edit">
        In Edit Mode
    </xsl:template>
    <xsl:template match="/" mode="view">
        In View Mode
    </xsl:template>
</xsl:stylesheet>
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = objXSLProcessor.input
objXMLDOMXSLProcessor.input = objXMLDOMNode

Example

Dim xslt As New Msxml2.XSLTemplate
Dim xslDoc As New Msxml2.FreeThreadedDOMDocument
Dim xmlDoc As New Msxml2.DOMDocument
Dim xslProc As IXSLProcessor
xslDoc.async = False
xslDoc.Load "sample2.xsl"
Set xslt.stylesheet = xslDoc
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set xslProc = xslt.createProcessor()
xslProc.input = xmlDoc
xslProc.Transform
MsgBox xslProc.output

Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html"/>
    <xsl:param name="param1"/>
    <xsl:template match="/">
        Hello
    </xsl:template>
    <xsl:template match="/" mode="edit">
        In Edit Mode
    </xsl:template>
    <xsl:template match="/" mode="view">
        In View Mode
    </xsl:template>
</xsl:stylesheet>
[C/C++]

C/C++ Syntax

HRESULT get_input (VARIANT * pVar);
HRESULT put_input (VARIANT pVar);

Parameters

pVar [out, retval][in]
The input XML to which to apply the transformation. This can be any object that supports ISequentialStream, IStream, or an IXMLDOMNode. If applying the transformation to an IXMLDOMNode, any node type and any threading model can be specified. If this argument is Null, the existing input will be cleared.

C/C++ Return Values

E_FAIL
The value returned if readyState is READYSTATE_INTERACTIVE.
E_INVALIDARG
The value returned if the variant is not VT_DISPATCH or VT_UNKNOWN.
E_NOINTERFACE
The value returned if the argument does not support IStream or IXMLDOMNode.

Remarks

Setting this property resets the state of the processor.

See Also

Applies to: IXSLProcessor


lastChild Property

Returns the last child node.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNode.lastChild;

Example

The following script example creates a new IXMLDOMNode (element) object, and then inserts it before the last child of the top-level node.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var newNode;
var currNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
var root = xmlDoc.documentElement;
alert(root.xml);
var newNode = xmlDoc.createNode(1, "VIDEOS", "");
currNode = root.insertBefore(newNode, root.lastChild);
alert(root.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNode.lastChild

Example

The following Microsoft® Visual Basic® example creates a new IXMLDOMNode (element) object, and then inserts it before the last child of the top-level node.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim newNode As IXMLDOMNode
Dim currNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
MsgBox root.xml
Set newNode = xmlDoc.createNode(NODE_ELEMENT, "VIDEOS", "")
Set currNode = root.insertBefore(newNode, root.lastChild)
MsgBox root.xml
[C/C++]

C/C++ Syntax

HRESULT get_lastChild(
    IXMLDOMNode **lastChild);

Parameters

lastChild [out, retval]
The last child node. If there are no children, it returns Null.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned when there are no children.
E_INVALIDARG
The value returned if lastChild is null.

Remarks

The property is read-only. If there are no children, it returns Null.

This value depends on the value of the nodeType property.

NODE_ATTRIBUTE, NODE_DOCUMENT, NODE_DOCUMENT_FRAGMENT, NODE_DOCUMENT_TYPE, NODE_ELEMENT, NODE_ENTITY, NODE_ENTITY_REFERENCE | Returns the last child node. If there are no children, returns Null.
NODE_CDATA_SECTION, NODE_COMMENT, NODE_NOTATION, NODE_PROCESSING_INSTRUCTION, NODE_TEXT | Returns Null. These node types cannot have children.

See Also

nodeType Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


length Property (IXMLDOMCharacterData)

Specifies the length, in characters, of the data.

[Script]

Script Syntax

lValue = oXMLDOMCharacterData.length;

Example

The following example creates an IXMLDOMComment object and then assigns the length property to a variable.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var comment;
var lValue;
xmlDoc.async = false;
xmlDoc.load("books.xml");
comment = xmlDoc.createComment("Hello World!");
lValue = comment.length;
alert(lValue);
[Visual Basic]

Visual Basic Syntax

lValue = oXMLDOMCharacterData.length

Example

The following example creates an IXMLDOMComment object and then assigns the length property to a variable.

Dim xmlDoc As New Msxml2.DOMDocument
Dim comment As IXMLDOMComment
Dim lValue As Long
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set comment = xmlDoc.createComment("Hello World!")
lValue = comment.length
MsgBox lValue
[C/C++]

C/C++ Syntax

HRESULT get_length(
    long *dataLength);

Parameters

dataLength [out, retval]
The length, in Unicode characters, of the string present in the data property.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if dataLength is Null.

Remarks

Long integer. The property is read-only. It specifies the length, in Unicode characters, of the string present in the data property.

See Also

data Property

Applies to: IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | IXMLDOMText


length Property (IXMLDOMNamedNodeMap)

Indicates the number of items in the collection.

[Script]

Script Syntax

lValue = oXMLDOMNamedNodeMap.length;

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeBook, namedNodeMap;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodeBook = xmlDoc.selectSingleNode("//book");
namedNodeMap = nodeBook.attributes;
alert(namedNodeMap.length);
[Visual Basic]

Visual Basic Syntax

lValue = oXMLDOMNamedNodeMap.length

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeBook As IXMLDOMElement
Dim namedNodeMap As IXMLDOMNamedNodeMap
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodeBook = xmlDoc.selectSingleNode("//book")
Set namedNodeMap = nodeBook.Attributes
MsgBox namedNodeMap.length
[C/C++]

C/C++ Syntax

HRESULT get_length(
    long *listLength);

Parameters

listLength [out, retval]
The number of items in the collection.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if listLength is Null.

Example

IXMLDOMNode *pIXMLDOMNode = NULL;
IXMLDOMNamedNodeMap *pIXMLDOMNamedNodeMap = NULL;
IXMLDOMElement *pIXMLDOMElement = NULL;
long lLength;
TCHAR strTemp[10];
HRESULT hr;
IXMLDOMDocument *pIXMLDOMDocument = NULL;

try
{
   // Create an instance of DOMDocument and initialize pIXMLDOMDocument.
   // Load/create an XML fragment.
   hr = pIXMLDOMDocument->get_documentElement(&pIXMLDOMElement);
   SUCCEEDED(hr) ? 0 : throw hr;

   if(pIXMLDOMElement)
   {
      hr = pIXMLDOMElement->get_attributes(&pIXMLDOMNamedNodeMap);
      if(SUCCEEDED(hr) && pIXMLDOMNamedNodeMap)
      {
         hr = pIXMLDOMNamedNodeMap->get_length(&lLength);
         if(SUCCEEDED(hr))
         {
            _itot(lLength, strTemp, 10);
            ::MessageBox(NULL, strTemp, _T("Number of Attributes"), MB_OK);
         }
         pIXMLDOMNamedNodeMap->Release();
         pIXMLDOMNamedNodeMap = NULL;
      }
      pIXMLDOMElement->Release();
      pIXMLDOMElement = NULL;
   }
}
catch(...)
{
   if(pIXMLDOMElement)
      pIXMLDOMElement->Release();
   if(pIXMLDOMNamedNodeMap)
      pIXMLDOMNamedNodeMap->Release();
   DisplayErrorToUser();
}
// Release pIXMLDOMDocument when finished with it.

Remarks

Long integer. The property is read-only.

See Also

Applies to: IXMLDOMNamedNodeMap


length Property (IXMLDOMNodeList)

Indicates the number of items in the collection.

[Script]

Script Syntax

lValue = oXMLDOMNodeList.length;

Example

The following script example creates an IXMLDOMNodeList object and then uses its length property to support iteration.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var objNodeList;
xmlDoc.async = false;
xmlDoc.load("books.xml");
objNodeList = xmlDoc.getElementsByTagName("author");
for (var i=0; i<objNodeList.length; i++) {
  alert(objNodeList.item(i).text);
}
[Visual Basic]

Visual Basic Syntax

lValue = oXMLDOMNodeList.length

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNodeList object and then uses its length property to support iteration.

Dim xmlDoc As New Msxml2.DOMDocument
Dim objNodeList As IXMLDOMNodeList
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set objNodeList = xmlDoc.getElementsByTagName("author")
For i = 0 To (objNodeList.length - 1)
  MsgBox objNodeList.Item(i).Text
Next
[C/C++]

C/C++ Syntax

HRESULT get_length(
    long *listLength);

Parameters

listLength [out, retval]
The number of items in the collection.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if listLength is Null.

Remarks

Long integer. The property is read-only.

See Also

Applies to: IXMLDOMNodeList | IXMLDOMSelection


length Property (XMLSchemaCache/IXMLSchemaCollection)

Returns the number of namespaces currently in the collection.

[Script]

Script Syntax

lValue = objXMLDOMSchemaCollection.length;
[Visual Basic]

Visual Basic Syntax

lValue = objXMLDOMSchemaCollection.length
[C/C++]

C/C++ Syntax

HRESULT length(long * length);

Parameters

length [out, retval]
The number of namespaces in the collection.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

Long integer. The property is read-only.

See Also

Applies to: IXMLSchemaCollection/XMLSchemaCache


line Property

Specifies the line number that contains the error.

[Script]

Script Syntax

lValue = oXMLDOMParseError.line;

Example

The following script example attempts to load an XML document. If it encounters a parse error, it displays the line where the error occurred.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
if (xmlDoc.parseError.errorCode != 0) {
  alert("A parse error occurred on line " + xmlDoc.parseError.line);
} else {
  alert(xmlDoc.documentElement.xml);
}
[Visual Basic]

Visual Basic Syntax

lValue = oXMLDOMParseError.line

Example

The following Microsoft® Visual Basic® example attempts to load an XML document. If it encounters a parse error, it displays the line where the error occurred.

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.async = False
xmlDoc.Load ("books.xml")
If xmlDoc.parseError.errorCode <> 0 Then
  MsgBox ("A parse error occurred on line " & xmlDoc.parseError.Line)
Else
  MsgBox xmlDoc.documentElement.xml
End If
[C/C++]

C/C++ Syntax

HRESULT get_line(
    long *lineNumber);

Parameters

lineNumber [out, retval]
The line number where the error occurred.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned if no error occurred.

Remarks

Long integer. The property is read-only.

See Also

Applies to: IXMLDOMParseError


linepos Property

Contains the character position within the line where the error occurred.

[Script]

Script Syntax

lValue = oXMLDOMParseError.linepos;

Example

The following script example attempts to load an XML document. If it encounters a parse error, it displays the line and position within that line where the error occurred.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
if (xmlDoc.parseError.errorCode != 0) {
  alert("A parse error occurred on line " + xmlDoc.parseError.line
  + " at position " + xmlDoc.parseError.linepos);
} else {
  alert(xmlDoc.documentElement.xml);
}
[Visual Basic]

Visual Basic Syntax

lValue = oXMLDOMParseError.linepos

Example

The following Microsoft® Visual Basic® example attempts to load an XML document. If it encounters a parse error, it displays the line and position within that line where the error occurred.

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.async = False
xmlDoc.Load ("books.xml")
If xmlDoc.parseError.errorCode <> 0 Then
  MsgBox ("A parse error occurred on line " & xmlDoc.parseError.Line _
  & " at position " & xmlDoc.parseError.linepos)
Else
  MsgBox xmlDoc.documentElement.xml
End If
[C/C++]

C/C++ Syntax

HRESULT get_linepos(
    long *linePosition);

Parameters

linePosition [out, retval]
The character position within the line where the error occurred.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned if no error occurred.

Remarks

Long integer. The property is read-only.

See Also

Applies to: IXMLDOMParseError


name Property (IXMLDOMAttribute)

Contains the attribute name.

[Script]

Script Syntax

strValue = oXMLDOMAttribute.name;

Example

The following script example creates an IXMLDOMAttribute object from the first attribute of the root, and then displays the value of its name.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var objDOMatt;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
objDOMatt = root.firstChild.attributes.item(0);
alert(objDOMatt.name);
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMAttribute.name

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMAttribute object from the first attribute of the root, and then displays the value of its name.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim objDOMatt As IXMLDOMAttribute
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
Set objDOMatt = root.firstChild.Attributes.Item(0)
MsgBox objDOMatt.Name
[C/C++]

C/C++ Syntax

HRESULT get_name(
    BSTR *attributeName);

Parameters

attributeName [out, retval]
Name of the attribute. The value is the same as the nodeName property of the IXMLDOMNode object.

C/C++ Return Values

S_OK
Value returned if successful.
S_FALSE
Value when returning Null.
E_INVALIDARG
Value returned if attributeName is Null.

Remarks

String. The property is read-only. It returns the name of the attribute. The value is the same as the nodeName property of the IXMLDOMNode.

See Also

nodeName Property | IXMLDOMNode

Applies to: IXMLDOMAttribute


name Property (IXMLDOMDocumentType)

Contains the name of the document type.

[Script]

Script Syntax

strValue = oXMLDOMDocumentType.name;
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMDocumentType.name
[C/C++]

C/C++ Syntax

HRESULT get_name(
    BSTR *rootName);

Parameters

rootName [out, retval]
When specified, this corresponds to the single root element of the document tree.

C/C++ Return Values

S_OK
Value returned if successful.
S_FALSE
Value when returning Null.

Example

BOOL DOMDocGetDocType()
{
   BOOL bResult = FALSE;
   IXMLDOMDocumentType *pIXMLDOMDocumentType = NULL;
   IXMLDOMDocument *pIXMLDOMDocument = NULL;
   IXMLDOMDocumentType *pIXMLDOMDocumentType = NULL;
   BSTR bstrDTDName;
   HRESULT hr;

   try
   {
      // Create an instance of DOMDocument and initialize
      // pIXMLDOMDocument.
      // Load/create an XML fragment.
      hr = pIXMLDOMDocument->get_doctype(&pIXMLDOMDocumentType);
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXMLDOMDocumentType)
      {
         pIXMLDOMDocumentType->get_name(&bstrDTDName);
         ::MessageBox(NULL, bstrDTDName, _T("Doc Type"), MB_OK);
         bResult = TRUE;
         pIXMLDOMDocumentType->Release();
      }
   }
   catch(...)
   {
      if(pIXMLDOMDocumentType)
         pIXMLDOMDocumentType->Release();
      DisplayErrorToUser();
   }
   return bResult;
}

Remarks

String. The property is read-only. When specified, this corresponds to the single root element of the document tree.

See Also

Applies to: IXMLDOMDocumentType


namespaces Property

Returns the list of namespaces used in the document as XMLSchemaCache.

[Script]

Script Syntax

objXMLDOMSchemaCollection = objIXMLDOMDocument2.namespaces;

Example

// Load a document (and any schemas referenced via X-Schema).
xmldoc.load ("somedata.xml");
// Get the namespace of the root element.
var namespaceURI = xmldoc.documentElement.namespaceURI;
// Find the schema associated with the namespace.
var schema = xmldoc.namespaces.get(namespaceURI);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMSchemaCollection = objIXMLDOMDocument2.namespaces

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim namespaceURI As String
Dim schema As XMLSchemaCache
' Load a document (and any schemas referenced via X-Schema).
xmlDoc.Load ("books.xml")
' Get the namespace of the root element.
namespaceURI = xmlDoc.documentElement.namespaceURI
' Find the schema associated with the namespace.
Set schema = xmlDoc.namespaces.get(namespaceURI)
[C/C++]

C/C++ Syntax

HRESULT get_namespaces (IXMLDOMSchemaCollection ** namespaceCollection);

Parameters

namespaceCollection [out, retval]
Collection of all namespaces for the document.

Remarks

If there are no schemas, it returns an empty collection.

See Also

Applies to: IXMLDOMSchemaCollection/XMLSchemaCache


namespaceURI Property (IXMLDOMNode)

Returns the Uniform Resource Identifier (URI) for the namespace.

[Script]

Script Syntax

strValue = oXMLDOMNode.namespaceURI;
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMNode.namespaceURI
[C/C++]

C/C++ Syntax

HRESULT get_namespaceURI(
    BSTR *namespaceURI);

Parameters

namespaceURI [out, retval]
URI for the namespace. This refers to the "uuu" portion of the namespace declaration xmlns:nnn="uuu".

C/C++ Return Values

S_OK
Value returned if successful.
S_FALSE
Value returned when there is no namespace.
E_INVALIDARG
Value returned if namespaceURI is Null.

Remarks

String. The property is read-only. Returns the URI for the namespace. This refers to the "uuu" portion of the namespace declaration xmlns:nnn="uuu".

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


namespaceURI Property (XMLSchemaCache/IXMLSchemaCollection)

Returns the namespace at the specified index.

[Script]

Script Syntax

strNamespaceURI = objXMLDOMSchemaCollection.namespaceURI(index);

Parameters

index
The index between 0 and (count-1).
[Visual Basic]

Visual Basic Syntax

strNamespaceURI = objXMLDOMSchemaCollection.namespaceURI(index)

Parameters

index
The index between 0 and (count-1).
[C/C++]

C/C++ Syntax

HRESULT namespaceURI(long index, BSTR* length);

Parameters

index [in]
The index between 0 and count -1.
length [out, retval]
The namespace URI at the given index. This string is a normalized version of the one provided in the add method (that is, leading and trailing white space is trimmed, new lines are converted to spaces, and multiple adjacent white space characters are collapsed into one space).

C/C++ Return Values

E_INVALIDARG
Value returned if the index is out of range.

Remarks

String. The namespaceURI property allows you to iterate through the collection to discover its contents. You can then use the get method (namespace) to see if there is an associated schema.

This is the default collection property, so you can do the following.

var uri = xmldoc.namespaces(1)

See Also

add Method | get Method

Applies to: XMLSchemaCache/IXMLDOMSchemaCollection


nextSibling Property

Contains the next sibling of the node in the parent's child list.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNode.nextSibling;

Example

The following script example creates an IXMLDOMNode object and sets it to the next sibling of the current node.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var currNode;
var nextNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
currNode = xmlDoc.documentElement.childNodes.item(0);
nextNode = currNode.nextSibling;
alert(nextNode.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNode.nextSibling

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNode object and sets it to the next sibling of the current node.

Dim xmlDoc As New Msxml2.DOMDocument
Dim currNode As IXMLDOMNode
Dim nextNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set currNode = xmlDoc.documentElement.childNodes.Item(0)
Set nextNode = currNode.nextSibling
MsgBox nextNode.xml
[C/C++]

C/C++ Syntax

HRESULT get_nextSibling(
    IXMLDOMNode **nextSibling);

Parameters

nextSibling [out, retval]
Right sibling of this node.

C/C++ Return Values

S_OK
Value returned if successful.
S_FALSE
Value returned when there is no next sibling.
E_INVALIDARG
Value returned if nextSibling is Null.

Remarks

The property is read-only. It returns the right sibling of this node.

This value depends on the value of the nodeType property.

NODE_ATTRIBUTE, NODE_DOCUMENT, NODE_DOCUMENT_FRAGMENT | Always returns Null; these node types do not appear as children of any other nodes.
NODE_CDATA_SECTION, NODE_COMMENT, NODE_DOCUMENT_TYPE, NODE_ELEMENT, NODE_ENTITY, NODE_ENTITY_REFERENCE, NODE_NOTATION, NODE_PROCESSING_INSTRUCTION, NODE_TEXT | Returns the node immediately following this node in the list of children of this node's parent. If no such node exists, returns Null.

See Also

nodeType Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


nodeName Property

Returns the qualified name for attribute, document type, element, entity, or notation nodes. Returns a fixed string for all other node types. Read-only.

[Script]

Script Syntax

strValue = oXMLDOMNode.nodeName;

Example

The following script example creates an IXMLDOMNode object and displays its name.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var currNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
currNode = xmlDoc.documentElement.childNodes.item(0);
alert(currNode.nodeName);
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMNode.nodeName

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNode object and displays its name.

Dim xmlDoc As New Msxml2.DOMDocument
Dim currNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set currNode = xmlDoc.documentElement.childNodes.Item(0)
MsgBox currNode.nodeName
[C/C++]

C/C++ Syntax

HRESULT get_nodeName(
    BSTR *name);

Parameters

name [out, retval]
Node name, which varies depending on the node type.

C/C++ Return Values

S_OK
Value returned if successful.
E_INVALIDARG
Value returned if name is Null.

Remarks

String. The property is read-only and always contains a non-empty string. The nodeName property contains the qualified name for the element, attribute, or entity reference. For example, it returns xxx:yyy for the element <xxx:yyy>.

The node name value varies, depending on the nodeType property.

NODE_ATTRIBUTE | Contains the name of the attribute.
NODE_CDATA_SECTION | Contains the literal string "#cdata-section".
NODE_COMMENT | Contains the literal string "#comment".
NODE_DOCUMENT | Contains the literal string "#document".
NODE_DOCUMENT_TYPE | Contains the name of the document type; for example, xxx in <!DOCTYPE xxx ...>.
NODE_DOCUMENT_FRAGMENT | Contains the literal string "#document-fragment".
NODE_ELEMENT | Contains the name of the XML tag, with any namespace prefix included if present.
NODE_ENTITY | Contains the name of the entity.
NODE_ENTITY_REFERENCE | Contains the name of the entity referenced. Note that the name does not include the leading ampersand or the trailing semicolon. The name includes the namespace if one is present.
NODE_NOTATION | Contains the name of the notation.
NODE_PROCESSING_INSTRUCTION | Contains the target; the first token following the <? characters.
NODE_TEXT | Contains the literal string "#text".

See Also

nodeType Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


nodeType Property

Specifies the XML Document Object Model (DOM) node type, which determines valid values and whether the node can have child nodes.

[Script]

Script Syntax

lValue = oXMLDOMNode.nodeType;

Example

The following script example creates an IXMLDOMNode object and displays its type enumeration, in this case, 1 for NODE_ELEMENT.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var currNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
currNode = xmlDoc.documentElement.childNodes.item(0);
alert(currNode.nodeType);
[Visual Basic]

Visual Basic Syntax

lValue = oXMLDOMNode.nodeType

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNode object and displays its type enumeration, in this case, 1 for NODE_ELEMENT.

Dim xmlDoc As New Msxml2.DOMDocument
Dim currNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set currNode = xmlDoc.documentElement.childNodes.Item(0)
MsgBox currNode.nodeType
[C/C++]

C/C++ Syntax

HRESULT get_nodeType(
    DOMNodeType *type);

Parameters

type [out, retval]
Type of the node.

C/C++ Return Values

S_OK
Value returned if successful.
E_INVALIDARG
Value returned if type is Null.

Remarks

Enumeration. The property is read-only. It indicates the type of the node. Use the nodeTypeString property to return the node type in string form.

The IXMLDOMNodeType enumeration defines the following valid values that can appear in the nodeType property.

NODE_ELEMENT (1) | The node represents an element. An element node can have the following child node types: Element, Text, Comment, ProcessingInstruction, CDATASection, and EntityReference. An element node can be the child of the Document, DocumentFragment, EntityReference, and Element nodes.
NODE_ATTRIBUTE (2) | The node represents an attribute of an element. An attribute node can have the following child node types: Text and EntityReference. An attribute does not appear as the child node of any other node type; note that it is not considered a child node of an element.
NODE_TEXT (3) | The node represents the text content of a tag. A text node cannot have any child nodes. A text node can appear as the child node of the Attribute, DocumentFragment, Element, and EntityReference nodes.
NODE_CDATA_SECTION (4) | The node represents a CDATA section in the XML source. CDATA sections are used to escape blocks of text that would otherwise be recognized as markup. A CDATA section node cannot have any child nodes. A CDATA section node can appear as the child of the DocumentFragment, EntityReference, and Element nodes.
NODE_ENTITY_REFERENCE (5) | The node represents a reference to an entity in the XML document. This applies to all entities, including character entity references. An entity reference node can have the following child node types: Element, ProcessingInstruction, Comment, Text, CDATASection, and EntityReference. An entity reference node can appear as the child of the Attribute, DocumentFragment, Element, and EntityReference nodes.
NODE_ENTITY (6) | The node represents an expanded entity. An entity node can have child nodes that represent the expanded entity (for example, Text and EntityReference nodes). An entity node can appear as the child of the DocumentType node.
NODE_PROCESSING_INSTRUCTION (7) | The node represents a processing instruction from the XML document. A processing instruction node cannot have any child nodes. A processing instruction node can appear as the child of the Document, DocumentFragment, Element, and EntityReference nodes.
NODE_COMMENT (8) | The node represents a comment in the XML document. A comment node cannot have any child nodes. A comment node can appear as the child of Document, DocumentFragment, Element, and EntityReference nodes.
NODE_DOCUMENT (9) | The node represents a document object, which, as the root of the document tree, provides access to the entire XML document. It is created using the progID "Msxml2.DOMDocument", or through a data island using <XML> or <SCRIPT LANGUAGE=XML>. A document node can have the following child node types: Element (maximum of one), ProcessingInstruction, Comment, and DocumentType. A document node cannot appear as the child of any node types.
NODE_DOCUMENT_TYPE (10) | The node represents the document type declaration, indicated by the <!DOCTYPE > tag. A document type node can have the following child node types: Notation and Entity. A document type node can appear as the child of the Document node.
NODE_DOCUMENT_FRAGMENT (11) | The node represents a document fragment. A document fragment node associates a node or subtree with a document without actually being contained within the document. A document fragment node can have the following child node types: Element, ProcessingInstruction, Comment, Text, CDATASection, and EntityReference. A DocumentFragment node cannot appear as the child of any node types.
NODE_NOTATION (12) | A node represents a notation in the document type declaration. A notation node cannot have any child nodes. A notation node can appear as the child of the DocumentType node.

See Also

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime | XML DOM Enumerated Constants


nodeTypedValue Property

Contains the node value expressed in its defined data type.

[Script]

Script Syntax

objValue = oXMLDOMNode.nodeTypedValue;
objXMLDOMNode.nodeTypedValue = objValue;

Example

var xmlDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xmlDocTest = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var strDestination;
var childNode;
xmlDoc.documentElement = xmlDoc.createElement("Test");
childNode = xmlDoc.createNode(3, "", "");
xmlDoc.documentElement.appendChild(childNode);
xmlDoc.documentElement.dataType = "bin.hex";
childNode.nodeTypedValue = "ffab123d";
xmlDocTest.async = false;
xmlDocTest.load(xmlDoc);
alert(xmlDocTest.xml);

Result (in a message box)

<Test xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="bin.hex">ffab123d</Test>
[Visual Basic]

Visual Basic Syntax

objValue = oXMLDOMNode.nodeTypedValue
objXMLDOMNode.nodeTypedValue = objValue

Example

Dim xmlDoc As New Msxml2.FreeThreadedDOMDocument
Dim xmlDocTest As New Msxml2.FreeThreadedDOMDocument
Dim strDestination As String
Dim childNode As IXMLDOMText
Set xmlDoc.documentElement = xmlDoc.createElement("Test")
Set childNode = xmlDoc.createNode(NODE_TEXT, "", "")
xmlDoc.documentElement.appendChild childNode
xmlDoc.documentElement.dataType = "bin.hex"
childNode.nodeTypedValue = "ffab123d"
xmlDocTest.async = False
xmlDocTest.Load xmlDoc
MsgBox xmlDocTest.xml

Result (in a message box)

<Test xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="bin.hex">ffab123d</Test>
[C/C++]

C/C++ Syntax

HRESULT get_nodeTypedValue(
    VARIANT *typedValue);
HRESULT put_nodeTypedValue(
    VARIANT typedValue);

Parameters

typedValue [out, retval][in]
Value of this node in its defined data type, if such a data type is defined. If this node has no content, the value of typedValue is Null.

C/C++ Return Values

S_OK
Value returned if successful.
E_INVALIDARG
Value returned if typedValue is Null.
E_FAIL (for put_nodeTypedValue only)
Value returned if an error occurs.

Remarks

Variant. The property is read/write. It returns the value of this node in its defined data type, if such a data type is defined. If the node has no content, this property returns Null.

This value depends on the value of the nodeType property of the IXMLDOMNode.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

The data type for this node is defined in its dataType property. This property also depends on the value of the node type, in the nodeType property.

Although you can explicitly set the nodeTypedValue property with a particular data type in the VARIANT, the set operation does not change the data type. The value in the VARIANT is coerced to the data type specified in the dataType property, and the set operation returns an error if the type coercion is not possible.

Changes to this property are also immediately available from the nodeValue property.

NODE_ATTRIBUTE | Returns the value in the data representation of the type specified in the schema for the attribute. (Data types are specified using the dt:dt attribute, and because attributes cannot be applied to attributes, the attribute's data type can be specified only in the schema.) If no type was specified, returns a string identical to the nodeValue property. If the new value is not of the type specified in the schema or cannot be coerced to the type specified in the schema, then an error occurs.
NODE_CDATA_SECTION, NODE_COMMENT, NODE_DOCUMENT, NODE_DOCUMENT_FRAGMENT, NODE_DOCUMENT_TYPE, NODE_ENTITY, NODE_NOTATION, NODE_PROCESSING_INSTRUCTION | Returns a string that is equal to the nodeValue property. These node types do not have data types.
NODE_ELEMENT | Returns the value in the data representation of the type specified on the element instance (using the dt:dt attribute) or specified in the schema. If no type was specified on the instance or in the schema, returns a string identical to the nodeValue property. If the element has an attribute data type, returns null.
NODE_ENTITY_REFERENCE | Returns the value in the data representation of the type specified for the referenced entity. This is limited to entities with a single data type on the root level element of the subtree corresponding to the entity. If no data type was specified, returns a string identical to the nodeValue property.
NODE_TEXT | Returns the value in the data representation of the type of the containing element. If the containing element was not typed, returns a string identical to the nodeValue property.

Data Type Mapping

VARIANT returned | Corresponding element data type
VT_BSTR | string
VT_BSTR | number
VT_I4 | Int
VT_CY | Fixed.14.4
VT_BOOL | Boolean
VT_DATE | dateTime
VT_DATE | dateTime.tz
VT_DATE | Date
VT_DATE | Time
VT_DATE | Time.tz
VT_I1 | i1 byte
VT_I2 | i2
VT_I4 | i4, int
VT_UI1 | ui1
VT_UI2 | ui2
VT_UI4 | ui4
VT_FLOAT | r4
VT_DOUBLE | r8, float
VT_BSTR | uuid
VT_ARRAY | bin.hex
VT_ARRAY | bin.base64

See Also

dataType Property | nodeType Property | nodeValue Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


nodeTypeString Property

Returns the node type in string form.

[Script]

Script Syntax

strValue = oXMLDOMNode.nodeTypeString;

Example

The following script example creates an IXMLDOMNode object and displays its node type in string form, in this case, "element".

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var currNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
currNode = xmlDoc.documentElement.childNodes.item(0);
alert(currNode.nodeTypeString);
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMNode.nodeTypeString

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNode object and displays its node type in string form, in this case, "element".

Dim xmlDoc As New Msxml2.DOMDocument
Dim currNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set currNode = xmlDoc.documentElement.childNodes.Item(0)
MsgBox currNode.nodeTypeString
[C/C++]

C/C++ Syntax

HRESULT get_nodeTypeString(
    BSTR *nodeType);

Parameters

nodeType [out, retval]
String version of the node type.

C/C++ Return Values

S_OK
Value returned if successful.
E_INVALIDARG
Value returned if nodeType is Null.

Remarks

String. The property is read-only. It contains the string version of the node type. To return the enumeration value, use the nodeType property.

This value depends on the value of the nodeType property.

NODE_ATTRIBUTE | attribute
NODE_CDATA_SECTION | cdatasection
NODE_COMMENT | comment
NODE_DOCUMENT | document
NODE_DOCUMENT_FRAGMENT | documentfragment
NODE_DOCUMENT_TYPE | documenttype
NODE_ELEMENT | element
NODE_ENTITY | entity
NODE_ENTITY_REFERENCE | entityreference
NODE_NOTATION | notation
NODE_PROCESSING_INSTRUCTION | processinginstruction
NODE_TEXT | text

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

nodeType Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


nodeValue Property

Contains the text associated with the node.

[Script]

Script Syntax

objValue = oXMLDOMNode.nodeValue;
objXMLDOMNode.nodeValue = objValue;

Example

The following script example creates an IXMLDOMNode object and tests if it is a comment node. If it is, it displays its value.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var currNode;
xmlDoc.async = false;
xmlDoc.async = false;
xmlDoc.loadXML("<root><!-- Hello --></root>");
currNode = xmlDoc.documentElement.childNodes.item(0);
if (currNode.nodeTypeString == "comment") {
  alert(currNode.nodeValue);
}
[Visual Basic]

Visual Basic Syntax

objValue = oXMLDOMNode.nodeValue
objXMLDOMNode.nodeValue = objValue

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNode object and tests if it is a comment node. If it is, it displays its value.

Dim xmlDoc As New Msxml2.DOMDocument
Dim currNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set currNode = xmlDoc.documentElement.childNodes.Item(0)
If currNode.nodeTypeString = "comment" Then
  MsgBox currNode.nodeValue
End If
[C/C++]

C/C++ Syntax

HRESULT get_nodeValue(
    VARIANT *value);
HRESULT put_nodeValue(
    VARIANT value);

Parameters

value [out, retval][in]
Node value; depends on the nodeType property.

C/C++ Return Values

S_OK
Value returned if successful.
S_FALSE (for get_nodeValue only)
Value when returning Null.
E_INVALIDARG (for get_nodeValue only)
Value returned if value is Null.
E_FAIL (for get_nodeValue only)
Value returned if an error occurs.

Remarks

Variant. The property is read/write.

This value depends on the value of the nodeType property.

NODE_ATTRIBUTE | Contains a string representing the value of the attribute. For attributes with subnodes, this is the concatenated text of all subnodes with entities expanded. Setting this value deletes all children of the node and replaces them with a single text node containing the value written.
NODE_CDATA_SECTION | Contains a string representing the text stored in the CDATA section.
NODE_COMMENT | Contains the content of the comment, exclusive of the comment's start and end sequence.
NODE_DOCUMENT, NODE_DOCUMENT_TYPE, NODE_DOCUMENT_FRAGMENT, NODE_ELEMENT, NODE_ENTITY, NODE_ENTITY_REFERENCE, NODE_NOTATION | Contains Null. Note that attempting to set the value of nodes of these types generates an error.
NODE_PROCESSING_INSTRUCTION | Contains the content of the processing instruction, excluding the target. (The target appears in the nodeName property.)
NODE_TEXT | Contains a string representing the text stored in the text node.

See Also

nodeName Property | nodeType Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


notationName Property

Contains the notation name.

[Script]

Script Syntax

strValue = oXMLDOMEntity.notationName;
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMEntity.notationName
[C/C++]

C/C++ Syntax

HRESULT get_notationName(
    BSTR *name);

Parameters

name [out, retval]
For unparsed entities, the name of the notation for the entity (the name following NDATA). For parsed entities, contains the empty string.

C/C++ Return Values

S_OK
Value returned if successful.
S_FALSE
Value returned when no notation is specified.
E_INVALIDARG
Value returned if name is Null.

Example

BOOL DOMEntityNotationName()
{
   BOOL bResult = FALSE;
   IXMLDOMEntity *pIXMLDOMEntity = NULL;
   BSTR bstrName ;
   HRESULT hr;

   try
   {
      pIXMLDOMEntity = GetFirstEntity();

      if(pIXMLDOMEntity)
      {
         hr =   pIXMLDOMEntity->get_notationName(&bstrName);
         ::MessageBox(NULL, bstrName, _T("Notation name"), MB_OK);
         bResult = TRUE;
         ::SysFreeString(bstrName);
         pIXMLDOMEntity->Release();
      }
   }
   catch(...)
   {
      if(pIXMLDOMEntity)
         pIXMLDOMEntity->Release();
      DisplayErrorToUser();
   }
   return bResult;
}
IXMLDOMEntity* GetFirstEntity()
{
   IXMLDOMNamedNodeMap *pIXMLDOMNamedNodeMapEntities = NULL;
   IXMLDOMEntity *pIXMLDOMEntity = NULL;
   IXMLDOMNode *pIXMLDOMNode = NULL;
   IXMLDOMDocument *pIXMLDOMDocument = NULL;
   HRESULT hr;

   try
   {
      // Create an instance of DOMDocument and initialize
      // pIXMLDOMDocument.
      // Load/create an XML fragment.
      hr = pIXMLDOMDocument->get_doctype(&pIXMLDOMDocumentType);
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXMLDOMDocumentType)
      {
         hr = pIXMLDOMDocumentType->get_entities
            (&pIXMLDOMNamedNodeMapEntities);
         if(SUCCEEDED(hr) && pIXMLDOMNamedNodeMapEntities)
         {
            hr = pIXMLDOMNamedNodeMapEntities->nextNode(&pIXMLDOMNode);
            if(SUCCEEDED(hr) && pIXMLDOMNode)
            {
               hr = pIXMLDOMNode->QueryInterface(IID_IXMLDOMEntity,
                  (void**)&pIXMLDOMEntity );
               SUCCEEDED(m_hr) ? 0 : throw m_hr;
               pIXMLDOMNode->Release();
            }
            pIXMLDOMNamedNodeMapEntities->Release();
         }
         pIXMLDOMDocumentType->Release();
      }
   }
   catch(...)
   {
      if(pIXMLDOMNode)
         pIXMLDOMNode->Release();
      if(m_pIXMLDOMNamedNodeMapEntities)
         m_pIXMLDOMNamedNodeMapEntities->Release();
      if(m_pIXMLDOMDocumentType)
         m_pIXMLDOMDocumentType->Release();
      DisplayErrorToUser();
   }
   // Release pIXMLDOMEntity when finished using it.
   // Release pIXMLDOMDocument when finished using it.
   return pIXMLDOMEntity;
}

Remarks

String. The property is read-only. For unparsed entities, the notationName property contains the name of the notation for the entity (the name following NDATA). For parsed entities, it contains the empty string. Note that the name of the entity is available using the nodeName property.

See Also

nodeName Property

Applies to: IXMLDOMEntity


notations Property

Contains a list of the IXMLDOMNotation members that are present in the document type declaration.

[Script]

Script Syntax

var objXMLDOMNamedNodeMap = oXMLDOMDocumentType.notations;
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNamedNodeMap = oXMLDOMDocumentType.notations
[C/C++]

C/C++ Syntax

HRESULT get_notations(
    IXMLDOMNamedNodeMap **notationMap);

Parameters

notationMap [out, retval]
List of IXMLDOMNotation that are present in the document type declaration.

C/C++ Return Values

S_OK
Value returned if successful.
E_INVALIDARG
Value returned if notationMap is Null.

Example

BOOL DOMDocTypeprops()
{
   BOOL bResult = FALSE;
   IXMLDOMDocument *pIXMLDOMDocument = NULL;
   IXMLDOMDocumentType *pIXMLDOMDocumentType = NULL;
   IXMLDOMNamedNodeMap *pIXMLDOMNamedNodeMapNotations = NULL;
   HRESULT hr;

   try
   {
      // Create an instance of DOMDocument and initialize
      // pIXMLDOMDocument.
      // Load/create an XML fragment.
      hr = pIXMLDOMDocument->get_doctype(&pIXMLDOMDocumentType);
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXMLDOMDocumentType)
      {
         hr = pIXMLDOMDocumentType->get_notations
            (&pIXMLDOMNamedNodeMapNotations);
         if(pIXMLDOMNamedNodeMapNotations)
         {
         // DisplayMapEntries(pIXMLDOMNamedNodeMapNotations)
            bResult = TRUE;
            pIXMLDOMNamedNodeMapNotations->Release();
         }
         pIXMLDOMDocumentType->Release();
      }
   }
   catch(...)
   {
      if(pIXMLDOMDocumentType)
         pIXMLDOMDocumentType->Release();
      if(pIXMLDOMNamedNodeMapNotations)
         pIXMLDOMNamedNodeMapNotations->Release();
      DisplayErrorToUser();
   }
   return bResult;
}

Remarks

The property is read-only. Notations identify by name the format of unparsed entities, the format of elements that bear a notation attribute, or the application to which a processing instruction is addressed.

See Also

IXMLDOMNotation

Applies to: IXMLDOMDocumentType


ondataavailable Property

Specifies the event handler for the ondataavailable event.

[Script]

Script Syntax

oXMLDOMDocument.ondataavailable = funcMyEventHandler;
[Visual Basic]

Visual Basic Syntax

objXMLDOMDocument.ondataavailable = value

Private WithEvents XmlDoc As Msxml2.DOMDocument
Private Sub XmlDoc_ondataavailable()
[C/C++]

C/C++ Syntax

HRESULT put_ondataavailable(
    VARIANT ondataavailableSink);

Parameters

ondataavailableSink [in]
Name of the function that should be called when the readyState property value changes to the value INTERACTIVE, indicating that data is available.

C/C++ Return Values

S_OK
Value returned if successful.

Remarks

The property is write-only. When handling asynchronous data, it is useful to be able to start processing in parallel with the download as soon as data becomes available. The ondataavailable event fires each time a new chunk of data arrives. The readyState property defines several states that specify the current status of the asynchronous download.

You can call QueryInterface method of the DOMDocument to obtain IConnectionPointContainer, which is used in event management. The DISPID for this event is DISPID_XMLDOMEVENT_ONDATAAVAILABLE.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

ondataavailable Event | readyState Property

Applies to: DOMDocument


onreadystatechange Property (DOMDocument)

Specifies the event handler to be called when the readyState property changes.

[Script]

Script Syntax

oXMLDOMDocument.onreadystatechange = funcMyEventHandler;
objXMLDOMDocument.onreadystatechange = value;

Example

The following script example specifies the handler CheckState gets called when the readyState property changes.

<script>
var xmldoc;
function Load(){
  xmldoc = new ActiveXObject("Msxml2.DOMDocument");
  xmldoc.onreadystatechange = CheckState;
  xmldoc.load(URL.value);
}
function CheckState(){
  var state = xmldoc.readyState;
  RESULTS.innerHTML += "readyState = " + state + "<BR>"
  if (state == 4){
    var err = xmldoc.parseError;
    if (err.errorCode != 0)
      RESULTS.innerHTML += err.reason +  "<BR>"
    else RESULTS.innerHTML += "Success" +  "<BR>"
  }
}
</script>
URL: <input type=text size=60 id=URL><input type=button value=LOAD onclick=jscript:Load()>
<div id=RESULTS style="color:red; font-weight:bold;"></div></script>

In Microsoft® Visual Basic® Scripting Edition (VBScript), you can get a function pointer using the syntax getRef("HandleStateChange").

[Visual Basic]

Visual Basic Syntax

Private WithEvents XmlDoc As Msxml2.DOMDocument
Private Sub XmlDoc_onreadystatechange()

Example

The following Microsoft Visual Basic example specifies the handler CheckState gets called when the readyState property changes.

Private WithEvents XmlDoc As Msxml2.DOMDocument
Private Sub cmdEvents_Click()
    Set XmlDoc = New Msxml2.DOMDocument
    XmlDoc.Load "books.xml"
End Sub
Private Sub XmlDoc_onreadystatechange()
    MsgBox "onreadystatechange: " & XmlDoc.readyState
End Sub
[C/C++]

C/C++ Syntax

HRESULT put_onreadystatechange(
    VARIANT readystatechangeSink);

Parameters

readystatechangeSink [in]
Name of the function that should be called when the readyState property value changes.

C/C++ Return Values

S_OK
Value returned if successful.

Remarks

The property is write-only. When using scripting languages, this property can be set in ways other than directly accessing the property through DOMDocument. It can also be set using the onreadystatechange attribute of the <XML> tag, and the SCRIPT FOR... construct.

You can call the QueryInterface method of the DOMDocument to obtain IConnectionPointContainer for event management. The DISPID for this event is DISPID_XMLDOMEVENT_ONREADYSTATECHANGE.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

onreadystatechange Event | readyState Property

Applies to: DOMDocument


onreadystatechange Property (IXMLHTTPRequest)

Specifies the event handler to be called when the readyState property changes. Note that onreadystatechange is designed for use in scripting environments and is not readily accessible in Microsoft® Visual Basic® or C++.

[Script]

Script Syntax

oXMLHttpRequest.onreadystatechange = funcMyHandler;

Example

The following script example specifies the handler HandleStateChange gets called when an IXMLHTTPRequest object's readyState property changes. A button on a page is enabled when the readyState property indicates that all data has been received (readystate == 4).

<script>
var xmlhttp=null;
function PostOrder(xmldoc)
{
  var xmlhttp = new ActiveXObject("Msxml2.XMLHttp");
  xmlhttp.Open("POST", "http://myserver/orders/processorder.asp", false);
  xmlhttp.onreadystatechange= HandleStateChange;
  xmlhttp.Send(xmldoc);
  myButton.disabled = true;
}
function HandleStateChange()
{
  if (xmlhttp.readyState == 4)
  {
    myButton.disabled = false;
    alert("Result = " + xmlhttp.responseXML.xml);
  }
}
</script>

In Microsoft Visual Basic® Scripting Edition (VBScript), you can get a function pointer using the syntax getRef("HandleStateChange").

[Visual Basic]

Visual Basic Syntax

oXMLHttpRequest.onreadystatechange = funcMyHandler
[C/C++]

C/C++ Syntax

HRESULT put_onreadystatechange(IDispatch* pReadyStateSink);

Parameters

pReadyStateSink [in]
Name of the function that should be called when the readyState property value changes.

C/C++ Return Values

S_OK
Value returned if successful.

Example

For a C/C++ example, see onreadystatechange Event.

Remarks

The property is write-only. When using scripting languages, this property can be set in ways other than directly accessing the property through IXMLHTTPRequest. It can also be set using the onreadystatechange attribute of the <XML> tag, and the SCRIPT FOR... construct.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

readyState Property

Applies to: IXMLHTTPRequest


onreadystatechange Property (ServerXMLHTTP/IServerXMLHTTPRequest)

Specifies the event handler to be invoked when the readyState property changes. Note that onreadystatechange is designed for use in scripting environments and is not readily accessible in Microsoft® Visual Basic® or C++.

Remarks

This event has the same syntax as the onreadystatechange event.

[Script]

Script Syntax

oServerXMLHTTPRequest.onreadystatechange = funcMyHandler;
[Visual Basic]

Visual Basic Syntax

oServerXMLHTTPRequest.onreadystatechange = funcMyHandler
[C/C++]

C/C++ Syntax

HRESULT put_onreadystatechange(VARIANT* readystatechangeSink);

Parameters

readystatechangeSink [in]
Name of the function that should be called when the readyState property value changes.

C/C++ Return Values

S_OK
Value returned if successful.

Example

For a C/C++ example, see onreadystatechange Event.

See Also

onreadystatechange Event | readyState Property

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


ontransformnode Property

Specifies the event handler for the ontransformnode event.

[Script]

Script Syntax

oXMLDOMDocument.ontransformnode = funcMyEventHandler;

Example

In this example, the XML data island named "target" contains the XML source data, and the XML data island named "ss" contains the XSL Transformations (XSLT) style sheet.

<XML id=target>
    <PEOPLE>
        <PERSON name="Atkinson, Teresa"  />
<PERSON name="Debroux, Steve" />
<PERSON name="O'Hara, Robert" />
<PERSON name="Porzuczek, Peter" />
    </PEOPLE>
</XML>
<XML id=ss>
  <xsl:template match="/" xmlns:xsl="http://www.w3.org/TR/WD-xsl">
   <xsl:for-each select="/PEOPLE/PERSON/@name" >
<P><xsl:value-of /></P>
   </xsl:for-each>
  </xsl:template>
</XML>

This script contains the Verify function, which sets the ontransformnode property to the event handler, onxform. The event handler is called before the transformation operation on each node, so given the sample data provided in the data islands, this sample calls the alert several times.

<SCRIPT LANGUAGE="javascript" FOR="window" EVENT="onload">
document.expando = false;
Verify();
</SCRIPT>
<Script LANGUAGE="javascript">
function onxform ( code, doc ) {
    alert("Target document node being transformed:\n\n" + doc.xml +
       "\n\nStylesheet node used for the transform:\n\n" + code.xml);
   if (doc.value == "O'Hara, Robert")
return false;  // stop processing
   else
return true;
}
function Verify() {
   target.ontransformnode = onxform;
   var sOut = target.XMLDocument.transformNode(ss.XMLDocument);
   div.innerHTML += sOut;
}
</Script>
<DIV id=div></DIV>
</BODY>
</HTML>

The return value from the event handler indicates whether to continue processing. In this example, the event handler checks for a particular data value and returns the value "false" to stop transformation processing.

[Visual Basic]

Visual Basic Syntax

oXMLDOMDocument.ontransformnode = funcMyEventHandler
[C/C++]

C/C++ Syntax

HRESULT put_ontransformnode(
    VARIANT ontransformnodeSink);

Parameters

ontransformnodeSink [in]
Name of the function that should be called when a transformation is about to be performed.

Remarks

The property is write-only. A transformation involves two trees: the XML source and the style sheet that is applied to it. The ontransformnode event fires before each node in the style sheet is applied to each node in the XML source.

The ontransformnode property provides a way for developers to specify an event handler to override the default handler.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

ontransformnode Event

Applies to: DOMDocument | transformNode Method


output Property

Gets a custom output to write the result of the transformation.

[Script]

Script Syntax

output = objXSLProcessor.output;
objXSLProcessor.output (output);

Parameters

output
The object to which to write the output of the transformation.

Example

var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xslProc;
xslDoc.async = false;
xslDoc.load("sample2.xsl");
xslt.stylesheet = xslDoc;
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
xslProc = xslt.createProcessor();
xslProc.input = xmlDoc;
xslProc.transform();
alert(xslProc.output);

Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[Visual Basic]

Visual Basic Syntax

output = objXSLProcessor.output
objXSLProcessor.output (output)

Parameters

output
The object to which to write the output of the transformation.

Example

Dim xslt As New Msxml2.XSLTemplate
Dim xslDoc As New Msxml2.FreeThreadedDOMDocument
Dim xmlDoc As New Msxml2.DOMDocument
Dim xslProc As IXSLProcessor
xslDoc.async = False
xslDoc.Load "sample2.xsl"
Set xslt.stylesheet = xslDoc
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set xslProc = xslt.createProcessor()
xslProc.input = xmlDoc
xslProc.Transform
MsgBox xslProc.output

Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[C/C++]

C/C++ Syntax

HRESULT get_output (VARIANT* pOutput);
HRESULT put_output (VARIANT output);

Parameters

pOutput [out, retval]
The custom output object or a BSTR containing the transformation result.
output [in]
The object to write the output of the transformation to.

C/C++ Return Values

E_NOINTERFACE
Value returned if the given output object does not support a supported interface.
E_FAIL
Value returned if readyState is READYSTATE_INTERACTIVE.

Remarks

The output property can be any object/interface that supports IStream, IPersistStream, DOMDocument, ASP IResponse, or ADODB.Stream.

When a new transform is started, the processor will use a QueryInterface this output for IStream. When the transform is complete or reset is called, IStream is released. The only method that is used on IStream is Write. The bytes written to the stream will be encoded according to the encoding attribute on the <xsl:output> element.

If you do not provide a custom output, then you will get a string when you read this property. The string contains the incrementally buffered transformation result.

Reading this property has the side effect of resetting that internal buffer so that each time you read the property you get the next chunk of output. In this case, the output is always generated in the Unicode encoding, and the encoding attribute on the <xsl:output> element is ignored.

See Also

Applies to: IXSLProcessor


ownerDocument Property

Returns the root of the document that contains the node.

[Script]

Script Syntax

var objXMLDOMDocument = oXMLDOMNode.ownerDocument;

Example

The following script example uses the ownerDocument property to return the parent DOMDocument object, and then displays that object's root element tag name.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var currNode;
var owner;
xmlDoc.async = false;
xmlDoc.load("books.xml");
currNode = xmlDoc.documentElement.childNodes.item(0).childNodes.item(1);
owner = currNode.ownerDocument;
alert(owner.documentElement.tagName);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMDocument = oXMLDOMNode.ownerDocument

Example

The following Microsoft® Visual Basic® example uses the ownerDocument property to return the parent DOMDocument object, and then displays that object's root element tag name.

Dim xmlDoc As New Msxml2.DOMDocument
Dim currNode As IXMLDOMNode
Dim owner As DOMDocument
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set currNode = xmlDoc.documentElement.childNodes.Item(0).childNodes.Item(1)
Set owner = currNode.ownerDocument
MsgBox owner.documentElement.tagName
[C/C++]

C/C++ Syntax

HRESULT get_ownerDocument(
    IXMLDOMDocument **DOMDocument);

Parameters

DOMDocument [out, retval]
Address of the parent document object that represents the root of the document.

C/C++ Return Values

S_OK
Value returned if successful.
E_INVALIDARG
Value returned if DOMDocument is Null.

Remarks

The property is read-only. It returns the parent document that represents the root of the document to which this node belongs.

All nodes are created in the context of a document, and the ownerDocument property is maintained until the node is added to another document. For a node removed from a document, this property indicates the document in which the node was last included.

See Also

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


ownerTemplate Property

Returns the style sheet template that was used to create IXSLProcessor.

[Script]

Script Syntax

var objXSLTemplate = objXSLProcessor.ownerTemplate;

Example

var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xslProc;
xslDoc.async = false;
xslDoc.load("sample2.xsl");
xslt.stylesheet = xslDoc;
xslProc = xslt.createProcessor();
alert(xslProc.ownerTemplate.stylesheet.xml);

Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[Visual Basic]

Visual Basic Syntax

Set objXSLTemplate = objXSLProcessor.ownerTemplate

Example

Dim xslt As New Msxml2.XSLTemplate
Dim xslDoc As New Msxml2.FreeThreadedDOMDocument
Dim xslProc As IXSLProcessor
xslDoc.async = False
xslDoc.Load "sample2.xsl"
Set xslt.stylesheet = xslDoc
Set xslProc = xslt.createProcessor()
MsgBox xslProc.ownerTemplate.stylesheet.xml

Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[C/C++]

C/C++ Syntax

HRESULT get_ownerTemplate (IXSLTemplate** ppTemplate);

Parameters

ppTemplate [out, retval]
The returned style sheet template property.

Remarks

The processor keeps the template active, so even if the user releases the template, this property can still be used to return the original template object.

Note The stylesheet property on the returned template may be different from the stylesheet property.

See Also

Applies to: IXSLProcessor


parentNode Property

Contains the parent node.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNode.parentNode;

Example

The following script example creates an IXMLDOMNode object from another node object's parent and displays its XML.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var currNode;
var newNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
currNode = xmlDoc.documentElement.childNodes.item(1).childNodes.item(0);
newNode = currNode.parentNode;
alert(newNode.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNode.parentNode

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNode object from another node object's parent and displays its XML.

Dim xmlDoc As New Msxml2.DOMDocument
Dim currNode As IXMLDOMNode
Dim newNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set currNode = xmlDoc.documentElement.childNodes.Item(1).childNodes.Item(0)
Set newNode = currNode.parentNode
MsgBox newNode.xml
[C/C++]

C/C++ Syntax

HRESULT get_parentNode(
    IXMLDOMNode **parent);

Parameters

parent [out, retval]
The parent of the given node instance.

C/C++ Return Values

S_FALSE
The value returned if there is no parent.
S_OK
The value returned if successful.
E_INVALIDARG
The value returned if parent is Null.

Remarks

The property is read-only. All nodes except Document, DocumentFragment, and Attribute nodes can have a parent. However, if a node has just been created and not yet added to the tree, or if it has been removed from the tree, the parent is Null.

This value depends on the value of the nodeType property.

NODE_ATTRIBUTE, NODE_DOCUMENT, NODE_DOCUMENT_FRAGMENT | Returns Null; these nodes do not have parents.
NODE_CDATA_SECTION | Returns the element or entity reference containing the CDATA section.
NODE_COMMENT | Returns the element, entity reference, document type, or document containing the comment.
NODE_DOCUMENT_TYPE | Returns the document node.
NODE_ELEMENT | Returns the parent node of the element. If the element is the root node in the tree, the parent is the document node. If the node is the document node, parentNode is Null.
NODE_ENTITY | Returns the document type node.
NODE_ENTITY_REFERENCE | Returns the element, attribute, or entity reference containing the entity reference.
NODE_NOTATION | Returns the document type node.
NODE_PROCESSING_INSTRUCTION | Returns the document, element, document type, or entity reference containing the processing instruction.
NODE_TEXT | Returns the parent element, attribute, or entity reference.

See Also

nodeType Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


parsed Property

Indicates the parsed status of the node and child nodes.

[Script]

Script Syntax

boolValue = oXMLDOMNode.parsed;

Example

The following script example displays whether or not the top-level node (root) and all its descendants are parsed.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
xmlDoc.async = true;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
alert(root.parsed);
[Visual Basic]

Visual Basic Syntax

boolValue = oXMLDOMNode.parsed

Example

The following Microsoft® Visual Basic® example displays whether the top-level node (root) and all its descendants are parsed.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
xmlDoc.async = True
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
MsgBox root.parsed
[C/C++]

C/C++ Syntax

HRESULT parsed(
    VARIANT_BOOL *isParsed);

Parameters

isParsed [out, retval]
True if this node and all descendants have been parsed; False if any descendants remain to be parsed.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if isParsed is Null.

Remarks

Boolean. The property is read-only. During asynchronous access, not all of the document tree may be available. Before performing some operations, such as XSL Transformations (XSLT) or pattern-matching operations, it is useful to know whether the entire tree below this node is available for processing.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

XSLT Reference

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


parseError Property

Returns an IXMLDOMParseError object that contains information about the last parsing error.

[Script]

Script Syntax

var objError = objXMLDOMDocument.parseError;

Example

The following script example uses the document's parseError property to create an IXMLDOMParseError object. It then tests the error and displays a message if one occurs.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var myErr;
xmlDoc.async = false;
xmlDoc.load("books.xml");
myErr = xmlDoc.parseError;
if (myErr.errorCode != 0) {
  alert("You have error " + myErr.reason);
}
[Visual Basic]

Visual Basic Syntax

Set objError = objXMLDOMDocument.parseError

Example

The following Microsoft® Visual Basic® example uses the document's parseError property to create an IXMLDOMParseError object. It then tests the error and displays a message if one occurs.

Dim xmlDoc As New Msxml2.DOMDocument
Dim myErr As IXMLDOMParseError
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set myErr = xmlDoc.parseError
If (myErr.errorCode <> 0) Then
  MsgBox ("You have error " & myErr.reason)
End If
[C/C++]

C/C++ Syntax

HRESULT get_parseError(
    IXMLDOMParseError **errorObj);

Parameters

errorObj [out, retval]
The DOMParseError object. The errorObj parameter is always a valid object.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if errorObj is Null.

Example

IXMLDOMParseError *pIParseError = NULL;
HRESULT hr;
IXMLDOMDocument *pIXMLDOMDocument = NULL;
wstring strOutput = _T("Load Error");

   // Initialize pIXMLDOMDocument (create a DOMDocument).
   // Load document.
try
{
   hr = pIXMLDOMDocument->get_parseError(&pIParseError);
   SUCCEEDED(hr) ? 0 : throw hr;

   if(pIParseError )
   {
      hr = pIParseError->get_errorCode(&value);
      if(SUCCEEDED(hr))
      {
         strOutput = (value != 0) ? _T("Load Error") : _T("Load
      Succeeded");
      }
      pIParseError->Release();
      pIParseError = NULL;
   }
}
catch(...)
{
   if(pIParseError)
      pIParseError->Release();
   DisplayErrorToUser();
}
// Release the IXMLDOMDocument interface when finished with it.

Remarks

The property is read-only. It returns IXMLDOMParseError.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

IXMLDOMParseError

Applies to: DOMDocument


prefix Property

Returns the namespace prefix.

[Script]

Script Syntax

strValue = oXMLDOMNode.prefix;
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMNode.prefix
[C/C++]

C/C++ Syntax

HRESULT get_prefix(
    BSTR *prefixString);

Parameters

prefixString [out, retval]
The namespace prefix specified on the element, attribute, or entity reference. For example, for the element <xxx:yyy>, it returns xxx. It returns an empty string, "", if no prefix is specified.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned when there is no prefix.
E_INVALIDARG
The value returned if prefixString is Null.

Remarks

String. The property is read-only. It returns the namespace prefix specified. For example, for the element <xxx:yyy>, it returns "xxx". It returns an empty string, "", if no prefix is specified.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | DOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


preserveWhiteSpace Property

Specifies the default white space handling.

[Script]

Script Syntax

boolVal = objXMLDOMDocument.preserveWhiteSpace;
objXMLDOMDocument.preserveWhiteSpace = boolVal;

Example

The following script example first loads and displays a file with the preserveWhiteSpace property set to True and then reloads and displays the file with the preserveWhiteSpace property set to False.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.preserveWhiteSpace = true;
xmlDoc.load("books.xml");
alert(xmlDoc.xml);
xmlDoc.async = false;
xmlDoc.preserveWhiteSpace = false;
xmlDoc.load("books.xml");
alert(xmlDoc.xml);
[Visual Basic]

Visual Basic Syntax

boolVal = objXMLDOMDocument.preserveWhiteSpace;
objXMLDOMDocument.preserveWhiteSpace = boolVal;

Example

The following Microsoft® Visual Basic® example first loads and displays a file with the preserveWhiteSpace property set to True and then reloads and displays the file with the preserveWhiteSpace property set to False.

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.async = False
xmlDoc.preserveWhiteSpace = True
xmlDoc.Load ("books.xml")
MsgBox xmlDoc.xml
xmlDoc.async = False
xmlDoc.preserveWhiteSpace = False
xmlDoc.Load ("books.xml")
MsgBox xmlDoc.xml
[C/C++]

C/C++ Syntax

HRESULT get_preserveWhiteSpace(
    VARIANT_BOOL *isPreserving);
HRESULT put_preserveWhiteSpace(
    VARIANT_BOOL isPreserving);

Parameters

isPreserving [out, retval][in]
The value that indicates whether default processing preserves white space.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG (for get_preserveWhiteSpace only)
The value returned if isPreserving is Null.

Remarks

Boolean. The property is read/write. This property is initialized to False.

The preserveWhiteSpace property specifies the default white space handling. When preserveWhiteSpace is True, all white space is preserved, regardless of any xml:space attributes specified in the document type definition (DTD). It is equivalent to having an xml:space= "preserve" attribute on every element.

When preserveWhiteSpace is False, the values of any xml:space attributes determine where white space is preserved.

The xml property does not preserve white space exactly as it appears in the original document. Instead, the object model replaces white space present in the original document with a single newline character in the representation returned by the xml property. In a similar way, the text property contains a representation without the leading and trailing spaces and replaces multiple intervening white space characters between words with a single space character.

The text and xml properties preserve white space when the preserveWhiteSpace property is set to True and xml:space on the XML element has the value "preserve."

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

text Property | xml Property

Applies to: DOMDocument


previousSibling Property

Contains the previous sibling of the node in the parent's child list.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNode.previousSibling;

Example

The following script example creates an IXMLDOMNode object and sets it to the previous sibling of the current node.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var currNode;
var prevNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
currNode = xmlDoc.documentElement.childNodes.item(1);
prevNode = currNode.previousSibling;
alert(prevNode.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNode.previousSibling

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNode object and sets it to the previous sibling of the current node.

Dim xmlDoc As New Msxml2.DOMDocument
Dim currNode As IXMLDOMNode
Dim prevNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set currNode = xmlDoc.documentElement.childNodes.Item(1)
Set prevNode = currNode.previousSibling
MsgBox prevNode.xml
[C/C++]

C/C++ Syntax

HRESULT get_previousSibling(
    IXMLDOMNode **previousSibling);

Parameters

previousSibling [out, retval]
The left sibling of this node.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned when there is no previous sibling.
E_INVALIDARG
The value returned if previousSibling is Null.

Remarks

The property is read-only.

This value depends on the value of the nodeType property.

NODE_ATTRIBUTE, NODE_DOCUMENT, NODE_DOCUMENT_FRAGMENT | Always returns Null; these node types do not appear as children of any other nodes.
NODE_CDATA_SECTION, NODE_COMMENT, NODE_DOCUMENT_TYPE, NODE_ELEMENT, NODE_ENTITY, NODE_ENTITY_REFERENCE, NODE_NOTATION, NODE_PROCESSING_INSTRUCTION, NODE_TEXT | Returns the node immediately preceding this node in its parent's child list. Returns Null if no such node exists.

See Also

nodeType Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


publicId Property (IXMLDOMEntity)

Contains the public identifier associated with the entity.

[Script]

Script Syntax

strValue = oXMLDOMEntity.publicId;
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMEntity.publicId
[C/C++]

C/C++ Syntax

HRESULT get_publicId(
    BSTR *publicID);

Parameters

publicID [out, retval]
The public identifier associated with the entity, if specified. If the public identifier is not specified, contains the empty string.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned if no public ID is specified.
E_INVALIDARG
The value returned if publicID is Null.

Example

IXMLDOMEntity *pIXMLDOMEntity = NULL;
VARIANT varName ;
HRESULT hr;

try
{
   // See help on IXMLDOMEntity::get_notationName method for definition of
   // the GetFirstEntity() method.
   pIXMLDOMEntity = GetFirstEntity();

   if(pIXMLDOMEntity)
   {
      hr = pIXMLDOMEntity->get_publicId(&varName);
      if(SUCCEEDED(hr))
         ::MessageBox(NULL, _bstr_t(varName), _T("Public ID"), MB_OK);
      pIXMLDOMEntity->Release();
   }
}
catch(...)
{
   if(pIXMLDOMEntity)
      pIXMLDOMEntity->Release();
   DisplayErrorToUser();
}

Remarks

String. The property is read-only. If the public identifier is not specified, the property contains the empty string.

See Also

Applies to: IXMLDOMEntity


publicId Property (IXMLDOMNotation)

Contains the public identifier for the notation.

[Script]

Script Syntax

strValue = oXMLDOMNotation.publicId;
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMNotation.publicId
[C/C++]

C/C++ Syntax

HRESULT get_publicId(
    VARIANT *publicID);

Parameters

publicID [out, retval]
The public identifier for the notation. If the public identifier is not specified, this contains an empty string.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if publicID is Null.

Remarks

Variant. The property is read-only. If the public identifier is not specified, the property contains the empty string.

See Also

Applies to: IXMLDOMNotation


readyState Property (DOMDocument)

Indicates the current state of the XML document.

[Script]

Script Syntax

lValue = oXMLDOMDocument.readyState;

Example

The following script example demonstrates the sequence of ready states when asynchronously loading a document.

<script>
var xmldoc;
function Load()
{
xmldoc = new ActiveXObject("Msxml2.DOMDocument");
xmldoc.onreadystatechange = CheckState;
xmldoc.load(URL.value);
}
function CheckState()
{
  var state = xmldoc.readyState;
  RESULTS.innerHTML += "readyState = " + state + "<BR>"
  if (state == 4)
  {
    var err = xmldoc.parseError;
    if (err.errorCode != 0)
      RESULTS.innerHTML += err.reason + "<BR>"
    else RESULTS.innerHTML +="success" + "<BR>"
  }
}
<script>
URL: <input type=text size=60 id=URL>
<input type=button value=LOAD onclick="jscript:Load()">
<div id=RESULTS style= "color:red;font-weight:bold;"></div>
[Visual Basic]

Visual Basic Syntax

lValue = oXMLDOMDocument.readyState

Example

The following Microsoft® Visual Basic® example demonstrates the sequence of ready states when asynchronously loading a document.

Dim WithEvents xmldoc As MSXML2.DOMDocument
Private Sub Command1_Click()
   Set xmldoc = New MSXML2.DOMDocument
   xmldoc.Load "books.xml"
End Sub
Private Sub xmldoc_onreadystatechange()
   Dim state As Integer
   state = xmldoc.readyState
   Text1.Text = Text1.Text & "readyState = " & state & vbCrLf
   If state = 4 Then
      If xmldoc.parseError.errorCode <> 0 Then
         Text1.Text = Text1.Text & xmldoc.parseError.reason & vbCrLf
      Else
         Text1.Text = Text1.Text & "success" & vbCrLf
      End If
   End If
End Sub
[C/C++]

C/C++ Syntax

HRESULT get_readyState(
    long * value);

Parameters

value [out, retval]
The value that indicates the instantiation and download state of the XML document object. It can be one of the following:

LOADING (1) | The load is in progress—reading persisted properties, but not yet parsing data. For readyState definitions, data should be considered equivalent to binary large object (BLOB) properties.
LOADED (2) | Reading of the persisted properties completed—reading and parsing data, but the object model is not yet available.
INTERACTIVE (3) | Some data has been read and parsed, and the object model is now available on the partially retrieved data set. Although the object model is available during this state, it is read-only.
COMPLETED (4) | The document has been completely loaded, successfully or unsuccessfully.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if value is Null.

Example

See the example in onreadystatechange Event.

Remarks

Long integer. The property is read-only. It returns a value that indicates the instantiation and download state of the XML document object. The value can be one of the following:

State | Description
LOADING (1) | The load is in progress—reading persisted properties, but not yet parsing data. For readyState definitions, data should be considered equivalent to binary large object (BLOB) properties.
LOADED (2) | Reading of the persisted properties completed—reading and parsing data, but the object model is not yet available.
INTERACTIVE (3) | Some data has been read and parsed, and the object model is now available on the partially retrieved data set. Although the object model is available during this state, it is read-only.
COMPLETED (4) | The document has been completely loaded, successfully or unsuccessfully.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

onreadystatechange Event

Applies to: DOMDocument


readyState Property (IXMLHTTPRequest)

Represents the state of the request.

Example

var XmlHttp;
XmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
XmlHttp.onreadystatechange = doHttpReadyStateChange;
XmlHttp.open("GET", "http://localhost/sample.xml", true);
XmlHttp.send();
function doHttpReadyStateChange() {
if (XmlHttp.readyState == 4) {
   alert("Done");
}
}
[Script]

Script Syntax

lValue = oXMLHttpRequest.readyState;
[Visual Basic]

Visual Basic Syntax

lValue = oXMLHttpRequest.readyState
[C/C++]

C/C++ Syntax

HRESULT get_readyState(long* plState);

Parameters

plState [out, retval]
State of the request, as an I4 (4-byte integer). The following values are defined:

(0) UNINITIALIZED | The object has been created, but not initialized (open has not been called).
(1) LOADING | The object has been created, but send has not been called.
(2) LOADED | send has been called and the status and headers are available, but the response is not yet available.
(3) INTERACTIVE | Some data has been received. You can call responseBody and responseText to get the current partial results.
(4) COMPLETED | All the data has been received, and the complete data is available in responseBody and responseText.

C/C++ Return Values

S_OK
Value returned if successful.

Remarks

Variant. The property is read-only. It represents the state of the request as an I4 (4-byte integer). The following values are defined.

0 (UNINITIALIZED) | The object has been created, but not initialized (open method has not been called).
(1) LOADING | The object has been created, but the send method has not been called.
(2) LOADED | The send method has been called and the status and headers are available, but the response is not yet available.
(3) INTERACTIVE | Some data has been received. You can call responseBody and responseText to get the current partial results.
(4) COMPLETED | All the data has been received, and the complete data is available in responseBody and responseText.

This property returns a 4-byte integer.

See Also

open Method | responseBody Property | responseText Property | send Method | status Property | statusText Property

Applies to: IXMLHTTPRequest


readyState Property (IXSLProcessor)

Returns the current state of the processor.

[Script]

Script Syntax

lReadyState = objXSLProcessor.readyState;

Example

var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xslProc;
xslDoc.async = false;
xslDoc.load("sample2.xsl");
xslt.stylesheet = xslDoc;
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
xslProc = xslt.createProcessor();
alert(xslProc.readyState);
xslProc.input = xmlDoc;
alert(xslProc.readyState);
[Visual Basic]

Visual Basic Syntax

lReadyState = objXSLProcessor.readyState

Example

Dim xslt As New Msxml2.XSLTemplate
Dim xslDoc As New Msxml2.FreeThreadedDOMDocument
Dim xmlDoc As New Msxml2.DOMDocument
Dim xslProc As IXSLProcessor
xslDoc.async = False
xslDoc.Load "sample2.xsl"
Set xslt.stylesheet = xslDoc
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set xslProc = xslt.createProcessor()
MsgBox xslProc.readyState
xslProc.input = xmlDoc
MsgBox xslProc.readyState
[C/C++]

C/C++ Syntax

HRESULT readyState (long* pReadyState);

Parameters

pReadyState [out, retval]
The state of the current transformation.

Remarks

The readyState property returns the current state of the processor as follows.

State | Description
READYSTATE_UNINITIALIZED (0) | This is the initial state until all the required properties (in particular, the input property) are set. Calling transform at this point returns an error.
READYSTATE_LOADING (1) | Not used by IXSLProcessor.
READYSTATE_LOADED (2) | This is the state in which all required properties are set. You can now call transform.
READYSTATE_INTERACTIVE (3) | transform has been called, but is not finished yet. Not used by IXSLProcessor.
READYSTATE_COMPLETE (4) | The transformation is finished, but there may still be some output to read if you are reading the output as a string. When you call reset or set any property, it reverts to READYSTATE_LOADED. If a required property is cleared, it reverts to READYSTATE_UNINITIALIZED.

See Also

Applies to: IXSLProcessor


readyState Property (ServerXMLHTTP/IServerXMLHTTPRequest)

Represents the state of the request.

[Script]

Script Syntax

lValue = oServerXMLHTTPRequest.readyState;

Example

var XmlServerHttp;
XmlServerHttp = new ActiveXObject("Msxml2.ServerXMLHTTP");
XmlServerHttp.onreadystatechange = doServerHttpReadyStateChange;
XmlServerHttp.open("GET", "http://localhost/sample.xml", true);
XmlServerHttp.send();
function doServerHttpReadyStateChange() {
if (XmlServerHttp.readyState == 4) {
      alert("Done");
}
}
[Visual Basic]

Visual Basic Syntax

lValue = oServerXMLHTTPRequest.readyState
[C/C++]

C/C++ Syntax

HRESULT get_readyState(long* pvarVal);

Parameters

pvarVal [out, retval]
The state of the request, as an I4 (4-byte integer). The following values are defined.

(0) UNINITIALIZED | The object has been created but has not been initialized because open method has not been called.
(1) LOADING | The object has been created but the send method has not been called.
(2) LOADED | The send method has been called and the status and headers are available, but the response is not yet available.
(3) INTERACTIVE | Some data has been received. You can call responseBody and responseText to get the current partial results.
(4) COMPLETED | All the data has been received, and the complete data is available in responseBody and responseText.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

This property returns a 4-byte integer.

See Also

open Method | responseBody Property | responseText Property | send Method | status Property | statusText Property

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


reason Property

Describes the reason for the error.

[Script]

Script Syntax

strValue = oXMLDOMParseError.reason;

Example

The following script example attempts to load an XML document. If it encounters a parse error, it uses the ParseError object's reason property to display the reason the error occurred.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
if (xmlDoc.parseError.errorCode != 0) {
   alert(xmlDoc.parseError.reason);
} else {
   alert(xmlDoc.documentElement.xml);
}
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMParseError.reason

Example

The following Microsoft® Visual Basic® example attempts to load an XML document. If it encounters a parse error, it uses the ParseError object's reason property to display the reason the error occurred.

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.async = False
xmlDoc.Load ("books.xml")
If xmlDoc.parseError.errorCode <> 0 Then
   MsgBox xmlDoc.parseError.reason
Else
   MsgBox xmlDoc.documentElement.xml
End If
[C/C++]

C/C++ Syntax

HRESULT get_reason(
    BSTR *reasonString);

Parameters

reasonString [out, retval]
The reason for the error. This displays a description of the error, the line number, character position, and source text of the error. Validation errors also include the URL of the schema and the node within the schema that corresponds to the error.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned if no error occurred.

Remarks

String. The property is read-only. It displays a description of the error. Validation errors also include the URL of the schema and the node within the schema that corresponds to the error.

See Also

Applies to: IXMLDOMParseError


resolveExternals Property

Indicates whether external definitions, resolvable namespaces, document type definition (DTD) external subsets, and external entity references, are to be resolved at parse time, independent of validation.

[Script]

Script Syntax

boolValue = oXMLDOMDocument.resolveExternals;
objXMLDOMDocument.resolveExternals = boolVal;

Example

The following script example sets the resolveExternals property to False before loading a document.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.resolveExternals = false;
xmlDoc.load("books.xml");
[Visual Basic]

Visual Basic Syntax

boolValue = oXMLDOMDocument.resolveExternals
objXMLDOMDocument.resolveExternals = boolVal;

Example

The following Microsoft® Visual Basic® example sets the resolveExternals property to False before loading a document.

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.async = False
xmlDoc.resolveExternals = False
xmlDoc.Load ("books.xml")
[C/C++]

C/C++ Syntax

HRESULT get_resolveExternals(
    VARIANT_BOOL *isResolving);
HRESULT put_resolveExternals(
    VARIANT_BOOL isResolving);

Parameters

isResolving [out, retval][in]
True if external definitions are to be resolved at parse time; False otherwise. The default is True.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG (for get_resolveExternals only)
The value returned if isResolving is Null.

Remarks

Boolean. The property is read/write.

When isResolving is True, external definitions are resolved at parse time. This allows default attributes and data types to be defined on elements from the schema and allows use of the DTD as a file inclusion mechanism.

This setting is independent of whether validation is to be performed, as indicated by the value of the validateOnParse property. If externals cannot be resolved during validation, a validation error occurs. When the value of isResolving is False, externals are not resolved and validation is not performed.

A resolvable namespace is indicated by a namespace Universal Resource Identifier (URI) that begins with "x-schema:" as its prefix.

The default setting is True.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

validateOnParse Property

Applies to: DOMDocument


responseBody Property (IXMLHTTPRequest)

Represents only one of several forms in which the HTTP response can be returned.

[Script]

Script Syntax

strValue = oXMLHttpRequest.responseBody;

Example

var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp.open("GET", "http://localhost/sample.xml", false);
xmlhttp.send();
alert(xmlhttp.responseBody);
[Visual Basic]

Visual Basic Syntax

strValue = oXMLHttpRequest.responseBody

Example

Dim xmlhttp As New Msxml2.xmlhttp
xmlhttp.open "GET", "http://localhost/sample.xml", False
xmlhttp.send
MsgBox xmlhttp.responseBody
[C/C++]

C/C++ Syntax

HRESULT get_responseBody(VARIANT* pvarBody);

Parameters

pvarBody [out, retval]
The response entity body as an array of unsigned bytes.

C/C++ Return Values

S_OK
The value returned if successful.
E_PENDING
The value returned if the data is unavailable.

Remarks

Variant. The property is read-only. Represents the response entity body as an array of unsigned bytes, namely a SAFEARRAY of type VT_ARRAY | VT_UI1. This contains the raw undecoded bytes as received directly from the server. Therefore, depending on what the server sent, this may appear as binary-encoded data (UTF-8, UCS-2, UCS-4, Shift_JIS, and so on).

See Also

responseStream Property | responseText Property | responseXML Property

Applies to: IXMLHTTPRequest


responseBody Property (ServerXMLHTTPRequest/IServerXMLHTTPRequest)

Represents the response entity body as an array of unsigned bytes, namely a SAFEARRAY of type VT_ARRAY | VT_UI1. This contains the raw undecoded bytes as received directly from the server. Depending on what the server sent, this can appear as binary-encoded data (UTF-8, UCS-2, UCS-4, Shift_JIS, and so on).

[Script]

Script Syntax

strValue = oServerXMLHTTPRequest.responseBody;
[Visual Basic]

Visual Basic Syntax

strValue = oServerXMLHTTPRequest.responseBody
[C/C++]

C/C++ Syntax

HRESULT get_responseBody(VARIANT* pvarVal);

Parameters

pvarVal [out, retval]
The response entity body as an array of unsigned bytes.

C/C++ Return Values

S_OK
The value returned if successful.
E_PENDING
The value returned if the data is unavailable.

Remarks

This property represents only one of several forms in which the HTTP response can be returned.

See Also

responseStream Property | responseText Property | responseXML Property

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


responseStream Property (IXMLHTTPRequest)

Represents only one of several forms in which the HTTP response can be returned.

[Script]

Script Syntax

strValue = oXMLHttpRequest.responseStream;
[Visual Basic]

Visual Basic Syntax

strValue = oXMLHttpRequest.responseStream
[C/C++]

C/C++ Syntax

HRESULT get_responseStream(VARIANT* pvarBody);

Parameters

pvarBody [out, retval]
The response entity body as an IStream.

C/C++ Return Values

S_OK
The value returned if successful.
E_PENDING
The value returned if the data is unavailable.

Example

HRESULT hr;
IXMLHttpRequest *pIXMLHttpRequest = NULL;
IStream *pIStream = NULL;
VARIANT varValue;

try
{
   // Create XMLHttpRequest object and initialize pIXMLHttpRequest.
   hr = pIXMLHttpRequest->get_responseStream(&varValue);
   if(SUCCEEDED(hr))
   {
      pIStream = (IStream*)varValue.punkVal;
      if(pIStream)
      {
         pIStream->Release();
         pIStream = NULL;
      }
   }
}
catch(...)
{
   if(pIStream)
      pIStream->Release();
   DisplayErrorToUser();
}
// Release pIXMLHttpRequest when finished with it.

Remarks

Variant. The property is read-only. Represents the response entity body as an IStream. This stream returns the raw undecoded bytes as received directly from the server. Therefore, depending on what the server sent, this may appear as binary-encoded data (UTF-8, UCS-2, UCS-4, Shift_JIS, and so on).

See Also

responseBody Property | responseText Property | responseXML Property

Applies to: IXMLHTTPRequest


responseStream Property (ServerXMLHTTP/IServerXMLHTTPRequest)

Represents the response entity body as an IStream. This stream returns the raw undecoded bytes as received directly from the server. Depending on what the server sent, this can appear as binary-encoded data (UTF-8, UCS-2, UCS-4, Shift_JIS, and so on).

[Script]

Script Syntax

strValue = oXMLHttpRequest.responseStream;
[Visual Basic]

Visual Basic Syntax

strValue = oXMLHttpRequest.responseStream
[C/C++]

C/C++ Syntax

HRESULT get_responseStream(VARIANT* pvarVal);

Parameters

pvarVal [out, retval]
The response entity body as an IStream.

C/C++ Return Values

S_OK
The value returned if successful.
E_PENDING
The value returned if the data is unavailable.

Remarks

This property represents only one of several forms in which the HTTP response can be returned.

See Also

responseBody Property | responseText Property | responseXML Property

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


responseText Property (IXMLHTTPRequest)

Represents the response entity body as a string.

[Script]

Script Syntax

strValue = oXMLHttpRequest.responseText;

Example

var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp.open("GET", "http://localhost/sample.xml", false);
xmlhttp.send();
alert(xmlhttp.responseText);
[Visual Basic]

Visual Basic Syntax

strValue = oXMLHttpRequest.responseText

Example

Dim xmlhttp As New Msxml2.xmlhttp
xmlhttp.open "GET", "http://localhost/sample.xml", False
xmlhttp.send
MsgBox xmlhttp.responseText
[C/C++]

C/C++ Syntax

HRESULT get_responseText(BSTR* pbstrBody);

Parameters

pbstrBody [out, retval]
The response entity body as a string.

C/C++ Return Values

S_OK
The value returned if successful.
E_PENDING
The value returned if the data is unavailable.

Remarks

Variant. The property is read-only. This property represents only one of several forms in which the HTTP response can be returned.

IXMLHTTP attempts to decode the response into a Unicode string. It assumes the default encoding is UTF-8, but can decode any type of UCS-2 (big or little endian) or UCS-4 encoding as long as the server sends the appropriate Unicode byte-order mark. It does not process the <? XML coding declaration. If you know the response is going to be XML, use the responseXML property for full XML encoding support.

See Also

responseBody Property | responseStream Property | responseXML Property

Applies to: IXMLHTTPRequest


responseText Property (ServerXMLHTTP/IServerXMLHTTPRequest)

Represents the response entity body as a string.

[Script]

Script Syntax

strValue = oServerXMLHTTPRequest.responseText;

Example

var xmlServerHttp = new ActiveXObject("Msxml2.ServerXMLHTTP");
xmlServerHttp.open("GET", "http://localhost/sample.xml", false);
xmlServerHttp.send();
alert(xmlServerHttp.responseText);
[Visual Basic]

Visual Basic Syntax

strValue = oServerXMLHTTPRequest.responseText

Example

Dim xmlServerHttp As New Msxml2.serverXmlHttp
xmlServerHttp.open "GET", "http://localhost/sample.xml", False
xmlServerHttp.send
MsgBox xmlServerHttp.responseText
[C/C++]

C/C++ Syntax

HRESULT get_responseText(VARIANT* pvarVal);

Parameters

pvarVal [out, retval]
The response entity body as a string.

C/C++ Return Values

S_OK
The value returned if successful.
E_PENDING
The value returned if the data is unavailable.

Remarks

ServerXMLHTTP/IServerXMLHTTPRequest tries to decode the response into a Unicode string. It assumes the default encoding is UTF-8, but it can decode any type of UCS-2 (big or little endian) or UCS-4 encoding as long as the server sends the appropriate Unicode byte-order mark. It does not process the <? XML coding declaration. If you know the response is going to be XML, use the responseXML property for full XML encoding support.

This property represents only one of several forms in which the HTTP response can be returned.

See Also

responseBody Property | responseStream Property | responseXML Property

Applies to: ServerXMLHTTP/IServerXMLHTTPRequest


responseXML Property (IXMLHTTPRequest)

Represents the parsed response entity body.

[Script]

Script Syntax

var objDispatch = oXMLHttpRequest.responseXML;

Example

var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp.open("GET", "http://localhost/sample.xml", false);
xmlhttp.send();
alert(xmlhttp.responseXML.xml);
[Visual Basic]

Visual Basic Syntax

Set objDispatch = oXMLHttpRequest.responseXML

Example

Dim xmlhttp As New Msxml2.xmlhttp
xmlhttp.open "GET", "http://localhost/sample.xml", False
xmlhttp.send
MsgBox xmlhttp.responseXML.xml
[C/C++]

C/C++ Syntax

HRESULT get_responseXML(IDispatch** ppBody);

Parameters

ppBody [out, retval]
The response entity body as an XML document.

C/C++ Return Values

S_OK
The value returned if successful.
E_PENDING
The value returned if the data is unavailable.

Remarks

The property is read-only. For security reasons, the parser validation features are always turned off to prevent the Microsoft® XML Parser (MSXML) from attempting to download a document type definition (DTD) or XML-Data definition. If the response entity body is not valid XML, this property returns DOMDocument that was parsed so that you can access the error. This property does not return IXMLDOMParseError itself, but it is accessible from DOMDocument.

If the response was generated by an Active Server Pages (ASP) page and the Multipurpose Internet Mail Extension (MIME) type was not correctly set to "text/xml" using the ASP method Response.ContentType, responseXML will be empty.

See Also

DOMDocument | IXMLDOMParseError | responseBody Property | responseStream Property | responseText Property

Applies to: IXMLHTTPRequest


responseXML Property (ServerXMLHTTP/IServerXMLHTTPRequest)

Represents the response entity body as parsed by the Microsoft® XML Parser (MSXML).

[Script]

Script Syntax

var objDispatch = oServerXMLHttpRequest.responseXML;

Example

var xmlServerHttp = new ActiveXObject("Msxml2.ServerXMLHTTP");
xmlServerHttp.open("GET", "http://localhost/sample.xml", false);
xmlServerHttp.send();
alert(xmlServerHttp.responseXML.xml);
[Visual Basic]

Visual Basic Syntax

Set objDispatch = oServerXMLHttpRequest.responseXML

Example

Dim xmlServerHttp As New Msxml2.serverXmlHttp
xmlServerHttp.open "GET", "http://localhost/sample.xml", False
xmlServerHttp.send
MsgBox xmlServerHttp.responseXML.xml
[C/C++]

C/C++ Syntax

HRESULT get_responseXML(IDispatch** ppXmlDom);

Parameters

ppXmlDom [out, retval]
The response entity body as an XML document.

C/C++ Return Values

S_OK
The value returned if successful.
E_PENDING
The value returned if the data is unavailable.

Remarks

For security reasons, the parser validation features are always turned off to prevent MSXML from attempting to download a document type definition (DTD) or XML-Data definition.

If the response entity body is not valid XML, this method returns the DOMDocument object that was parsed so that you can access the error object. This property does not return the error object IXMLDOMParseError itself. That object is accessible from the DOMDocument object.

If the response was generated by an Active Server Pages (ASP) page and the Multipurpose Internet Mail Extension (MIME) type was not correctly set to "text/xml" or "application/xml" using the ASP method Response.ContentType, responseXML will be empty.

See Also

DOMDocument | IXMLDOMParseError | responseBody Property | responseStream Property | responseText Property

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


schemas Property

Finds schema documents during load.

[Script]

Script Syntax

var objXMLDOMSchemaCollection = objIXMLDOMDocument2.schemas;
objXMLDOMDocument.schemas = objXMLDOMSchemaCollection;
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMSchemaCollection = objIXMLDOMDocument2.schemas
objXMLDOMDocument.schemas = objXMLDOMSchemaCollection
[C/C++]

C/C++ Syntax

HRESULT get_schemas (VARIANT* otherCollection);
HRESULT putref_schemas (VARIANT otherCollection);

Parameters

otherCollection [out, retval][in]
The schema collection that is returned. This is the same object that was previously set, or Null if none has been set.

C/C++ Return Values

S_OK
The value returned if the method executes successfully and a schema collection is set.
S_FALSE (for get_schemas only)
The value returned if no schema collection is set.
E_POINTER (for get_schemas only)
The value returned if pSchemaCollection = Null.
E_FAIL (for putref_schemas only)
The value returned if an IXMLSchemaCollection interface cannot be obtained from SchemaCollection with formatted IErrorInfo.

Null if no schema collection is currently set. You will always get the same collection object you enter.

Example

#import "msxml3.dll"
using namespace MSXML2;

#define CHECK_AND_RELEASE(pInterface)  \
if(pInterface) \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

#define RELEASE(pInterface)  \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

BOOL DOMDocument2schemas()
{
   BOOL bResult = FALSE;
   short sResult = FALSE;
   IXMLDOMNodeList *pIXMLDOMNodeList=NULL;
   IXMLDOMDocument2 *pIXMLDOMDocument2=NULL;
   IXMLDOMSchemaCollection *pIXMLDOMSchemaCollection=NULL;
   HRESULT hr;
   BSTR bstrValue;
   VARIANT varValue;

   try
   {
      hr=CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_SERVER,
IID_IXMLDOMDocument2, (LPVOID*)(&pIXMLDOMDocument2));
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXMLDOMDocument2)
      {
         hr=pIXMLDOMDocument2->put_async(VARIANT_FALSE);
         if(SUCCEEDED(hr))
         {
            hr=CoCreateInstance(CLSID_XMLSchemaCache, NULL, CLSCTX_SERVER,
               IID_IXMLDOMSchemaCollection,
               (LPVOID*)(&pIXMLDOMSchemaCollection));
            SUCCEEDED(hr) ? 0 : throw hr;

            if(SUCCEEDED(hr) && pIXMLDOMSchemaCollection)
            {
               hr = pIXMLDOMSchemaCollection->add(_T("x-schema:books"),
            _variant_t(_T("d:\\inetpub\\wwwroot\\bookschema.xml")));
               if(SUCCEEDED(hr))
               {
                  varValue.vt = VT_DISPATCH;
                  varValue.pdispVal = pIXMLDOMSchemaCollection;
                  hr=pIXMLDOMDocument2->putref_schemas(varValue);

                  // The document will load only if a valid schema is
                  // attached to the xml file.
                  hr=pIXMLDOMDocument2->load(_variant_t(
            _T("d:\\inetpub\\wwwroot\\samplexmldtd.xml")),
      &sResult);
                  if(SUCCEEDED(hr) && (sResult==VARIANT_TRUE))
                  {
                     pIXMLDOMDocument2->get_xml(&bstrValue);
                     ::MessageBox(NULL, bstrValue, _T("Loaded Document"),
                        MB_OK);
                     bResult=TRUE;
                  }
               }
               RELEASE(pIXMLDOMSchemaCollection);
            }
         }
         RELEASE(pIXMLDOMDocument2);
      }
   }
   catch(...)
   {
      CHECK_AND_RELEASE(pIXMLDOMDocument2);
      CHECK_AND_RELEASE(pIXMLDOMNodeList);
      CHECK_AND_RELEASE(pIXMLDOMSchemaCollection);
      DisplayErrorToUser();
   }
   return bResult;
}

File Name: d:\inetpub\wwwroot\samplexmldtd.xml

<?xml version='1.0'?>
<COLLECTION xmlns="x-schema:books"
   xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
   <BOOK>
      <TITLE>Cosmos</TITLE>
      <AUTHOR>Carl Sagan</AUTHOR>
      <PUBLISHER>Ballantine Books</PUBLISHER>
   </BOOK>
   <BOOK>
      <TITLE>Catwings</TITLE>
      <AUTHOR>Ursula K. Le Guin</AUTHOR>
      <PUBLISHER>Scholastic</PUBLISHER>
   </BOOK>
   <BOOK>
      <TITLE>Home Town</TITLE>
      <AUTHOR>Tracy Kidder</AUTHOR>
      <PUBLISHER>Random House</PUBLISHER>
   </BOOK>
</COLLECTION>

File Name: d:\inetpub\wwwroot\bookschema.xml

<?xml version="1.0"?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data">
   <ElementType name="TITLE" />
   <ElementType name="AUTHOR" />
   <ElementType name="PUBLISHER" />
   <ElementType name="DATE" />
   <ElementType name="BOOK" model="closed">
      <element type="TITLE" />
      <element type="AUTHOR" />
      <element type="PUBLISHER" />
   </ElementType>
   <ElementType name="COLLECTION" model="closed">
      <element type="BOOK" />
   </ElementType>
</Schema>

Remarks

The schemas property provides a way to associate preloaded schemas with any namespace. It also provides a way to override the schemas that are used by the document you are about to load. Setting a new schema collection has no effect on the current document until the next load or loadXML call. The schemas loaded by the document during load are not added automatically to this collection.

Setting any non-null schema collection automatically disables document type definition (DTD) processing because you cannot use both DTD and XML schema processing on the same document. This means DTDs will be ignored. Setting the schemas collection to Null reenables DTD processing.

See Also

IXMLDOMSchemaCollection/XMLSchemaCache

Applies to: IXMLDOMDocument2


specified Property

Indicates whether the node (usually an attribute) is explicitly specified or derived from a default value in the document type definition (DTD) or schema.

[Script]

Script Syntax

boolValue = oXMLDOMNode.specified;

Example

The following script example creates an IXMLDOMNode from the specified item in an IXMLDOMNamedNodeMap. It then displays whether or not the attribute was specified in the element, rather than in a DTD or schema.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var currNode;
var objNamedNodeMap;
var myNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
currNode = xmlDoc.documentElement.childNodes.item(0);
objNamedNodeMap = currNode.attributes;
myNode = objNamedNodeMap.item(0);
alert(myNode.specified);
[Visual Basic]

Visual Basic Syntax

boolValue = oXMLDOMNode.specified

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNode from the specified item in an IXMLDOMNamedNodeMap. It then displays whether or not the attribute was specified in the element, rather than in a DTD or schema.

Dim xmlDoc As New Msxml2.DOMDocument
Dim currNode As IXMLDOMNode
Dim objNamedNodeMap As IXMLDOMNamedNodeMap
Dim myNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set currNode = xmlDoc.documentElement.childNodes.Item(0)
Set objNamedNodeMap = currNode.Attributes
Set myNode = objNamedNodeMap.Item(0)
MsgBox myNode.specified
[C/C++]

C/C++ Syntax

HRESULT get_specified(
    VARIANT_BOOL *isSpecified);

Parameters

isSpecified [out, retval]
True if the attribute is explicitly specified in the element; False if the attribute value comes from the DTD or schema.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if isSpecified is Null.

Remarks

Boolean. The property is read-only. Returns True if the attribute is explicitly specified in the element. Returns False if the attribute value comes from the DTD or schema.

This value depends on the value of the nodeType property.

NODE_ATTRIBUTE | Returns True if the attribute was specified directly on the element. Returns False for default attributes.
NODE_CDATA_SECTION, NODE_COMMENT, NODE_DOCUMENT, NODE_DOCUMENT_FRAGMENT, NODE_DOCUMENT_TYPE, NODE_ELEMENT, NODE_ENTITY, NODE_ENTITY_REFERENCE, NODE_NOTATION, NODE_PROCESSING_INSTRUCTION, NODE_TEXT | Returns True.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

nodeType Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


srcText Property

Returns the full text of the line containing the error.

[Script]

Script Syntax

strValue = oXMLDOMParseError.srcText;

Example

The following script example attempts to load an XML document. If it encounters a parse error, it displays the text of the line containing the error.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
if (xmlDoc.parseError.errorCode != 0) {
  alert(xmlDoc.parseError.srcText);
} else {
  alert(xmlDoc.documentElement.xml);
}
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMParseError.srcText

Example

The following Microsoft® Visual Basic® example attempts to load an XML document. If it encounters a parse error, it displays the text of the line containing the error.

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.async = False
xmlDoc.Load ("books.xml")
If xmlDoc.parseError.errorCode <> 0 Then
  MsgBox xmlDoc.parseError.srcText
Else
  MsgBox xmlDoc.documentElement.xml
End If
[C/C++]

C/C++ Syntax

HRESULT get_srcText(
    BSTR *sourceString);

Parameters

sourceString [out, retval]
The full text of the line containing the error. This returns an empty string if the error is caused by XML that is not well-formed and cannot be assigned to a specific line.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned if no error occurred.

Remarks

String. The property is read-only. It returns an empty string if an error is caused by XML that is not well-formed and cannot be assigned to a specific line.

See Also

Applies to: IXMLDOMParseError


startMode Property

Returns the base name part of the start mode, a qualified name.

[Script]

Script Syntax

objXSLProcessor.startMode(mode);

Example

var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xslProc;
xslDoc.async = false;
xslDoc.load("sample2.xsl");
xslt.stylesheet = xslDoc;
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
xslProc = xslt.createProcessor();
xslProc.input = xmlDoc;
xslProc.setStartMode("view");
alert(xslProc.startMode);

File Name: Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[Visual Basic]

Visual Basic Syntax

objXSLProcessor.startMode(mode)

Example

Dim xslt As New Msxml2.XSLTemplate
Dim xslDoc As New Msxml2.FreeThreadedDOMDocument
Dim xmlDoc As New Msxml2.DOMDocument
Dim xslProc As IXSLProcessor
xslDoc.async = False
xslDoc.Load "sample2.xsl"
Set xslt.stylesheet = xslDoc
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set xslProc = xslt.createProcessor()
xslProc.input = xmlDoc
xslProc.setStartMode "view"
MsgBox xslProc.StartMode

File Name: Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[C/C++]

C/C++ Syntax

HRESULT startMode(BSTR mode);

Parameters

mode [in]
The desired mode as a string. It must be the base name part of the qualified name.

C/C++ Return Values

E_FAIL
The value returned if readyState is READYSTATE_INTERACTIVE.
E_INVALIDARG
The value returned if the mode base name contains a colon character or is an invalid name.

Remarks

The default value of startMode is the empty string, "".

See Also

Applies to: IXSLProcessor

Other Resources Other Resources

Worldwide Web Consortium XSL Transformations (XSLT) Version 1.0 Recommendation | Worldwide Web Consortium Namespaces in XML Recommendation


startModeURI Property

Returns the namespace URI part of the start mode, the qualified name.

[Script]

Script Syntax

strNamespace = objXSLProcessor.startModeURI;

Example

var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xslProc;
xslDoc.async = false;
xslDoc.load("sample2.xsl");
xslt.stylesheet = xslDoc;
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
xslProc = xslt.createProcessor();
xslProc.input = xmlDoc;
xslProc.setStartMode("view");
alert(xslProc.startModeURI);

File Name: Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[Visual Basic]

Visual Basic Syntax

strNamespace = objXSLProcessor.startModeURI

Example

Dim xslt As New Msxml2.XSLTemplate
Dim xslDoc As New Msxml2.FreeThreadedDOMDocument
Dim xmlDoc As New Msxml2.DOMDocument
Dim xslProc As IXSLProcessor
xslDoc.async = False
xslDoc.Load "sample2.xsl"
Set xslt.stylesheet = xslDoc
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set xslProc = xslt.createProcessor()
xslProc.input = xmlDoc
xslProc.setStartMode "view"
MsgBox xslProc.startModeURI

File Name: Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[C/C++]

C/C++ Syntax

HRESULT get_startModeURI(BSTR * namespaceURI);

Parameters

namespaceURI [out, retval]
The namespace URI of the starting Extensible Stylesheet Language (XSL) mode.

Remarks

The default value of this property is the empty string, "".

See Also

Applies to: IXSLProcessor

Other Resources Other Resources

Worldwide Web Consortium XSL Transformations (XSLT) Version 1.0 Recommendation


status Property (IXMLHTTPRequest)

Represents the HTTP status code returned by a request.

[Script]

Script Syntax

lValue = oXMLHttpRequest.status;

Example

var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp.open("GET", "http://localhost/sample.xml", false);
xmlhttp.send();
alert(xmlhttp.status);
[Visual Basic]

Visual Basic Syntax

lValue = oXMLHttpRequest.status

Example

Dim xmlServerHttp As New Msxml2.serverXmlHttp
xmlServerHttp.open "GET", "http://localhost/sample.xml", False
xmlServerHttp.send
MsgBox xmlServerHttp.status
[C/C++]

C/C++ Syntax

HRESULT get_status(long* plStatus);

Parameters

plStatus [out, retval]
The returned status code, as a long integer.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

Long integer. The property is read-only. It represents the returned status code as a long integer. This value is valid only after the send method returns successfully.

See Also

send Method | statusText Property

Applies to: IXMLHTTPRequest


status Property (ServerXMLHTTP/IServerXMLHTTPRequest)

Represents the HTTP status code returned by a request.

[Script]

Script Syntax

lValue = oServerXMLHTTPRequest.status;

Example

var xmlServerHttp = new ActiveXObject("Msxml2.ServerXMLHTTP");
xmlServerHttp.open("GET", "http://localhost/sample.xml", false);
xmlServerHttp.send();
alert(xmlServerHttp.status);
[Visual Basic]

Visual Basic Syntax

lValue = oServerXMLHTTPRequest.status

Example

Dim xmlServerHttp As New Msxml2.serverXmlHttp
xmlServerHttp.open "GET", "http://localhost/sample.xml", False
xmlServerHttp.send
MsgBox xmlServerHttp.Status
[C/C++]

C/C++ Syntax

HRESULT get_status(long* plStatus);

Parameters

plStatus [out, retval]
The returned status code, as a long integer.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

The results of this method are valid only after the send method has been successfully completed.

See Also

send Method | statusText Property

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


statusText Property (IXMLHTTPRequest)

Represents the HTTP response line status.

[Script]

Script Syntax

strValue = oXMLHttpRequest.statusText;

Example

var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp.open("GET", "http://localhost/sample.xml", false);
xmlhttp.send();
alert(xmlhttp.statusText);
[Visual Basic]

Visual Basic Syntax

strValue = oXMLHttpRequest.statusText

Example

Dim xmlhttp As New Msxml2.xmlhttp
xmlhttp.open "GET", "http://localhost/sample.xml", False
xmlhttp.send
MsgBox xmlhttp.Status
[C/C++]

C/C++ Syntax

HRESULT get_statusText(BSTR* pbstrStatus);

Parameters

pbstrStatus [out, retval]
The HTTP response as a "BSTR" value.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

String. The property is read-only. It represents the HTTP response as a BSTR value. This value is valid only after the send method returns successfully.

See Also

send Method | status Property

Applies to: IXMLHTTPRequest


statusText Property (ServerXMLHTTP/IServerXMLHTTPRequest)

Represents the HTTP response line status.

[Script]

Script Syntax

strValue = oXMLHttpRequest.statusText;

Example

var xmlServerHttp = new ActiveXObject("Msxml2.ServerXMLHTTP");
xmlServerHttp.open("GET", "http://localhost/sample.xml", false);
xmlServerHttp.send();
alert(xmlServerHttp.statusText);
[Visual Basic]

Visual Basic Syntax

strValue = oXMLHttpRequest.statusText

Example

Dim xmlServerHttp As New Msxml2.serverXmlHttp
xmlServerHttp.open "GET", "http://localhost/sample.xml", False
xmlServerHttp.send
MsgBox xmlServerHttp.statusText
[C/C++]

C/C++ Syntax

HRESULT get_statusText(BSTR* pbstrStatus);

Parameters

pbstrStatus [out, retval]
The HTTP response as a "BSTR" value.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

The results of this method are valid only after the send method has been successfully completed.

See Also

send method | status Property

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


stylesheet Property (IXSLProcessor)

Provides the Extensible Stylesheet Language (XSL) style sheet that is to be compiled into the XSL template.

[Script]

Script Syntax

var objXMLDOMNode = objXSLProcessor.stylesheet;

Example

var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xslProc;
xslDoc.async = false;
xslDoc.load("sample2.xsl");
xslt.stylesheet = xslDoc;
xslProc = xslt.createProcessor();
alert(xslProc.stylesheet.xml);

File Name: Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = objXSLProcessor.stylesheet

Example

Dim xslt As New Msxml2.XSLTemplate
Dim xslDoc As New Msxml2.FreeThreadedDOMDocument
Dim xslProc As IXSLProcessor
xslDoc.async = False
xslDoc.Load "sample2.xsl"
Set xslt.stylesheet = xslDoc
Set xslProc = xslt.createProcessor()
MsgBox xslProc.stylesheet.xml

File Name: Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[C/C++]

C/C++ Syntax

HRESULT get_stylesheet (IXMLDOMNode** stylesheet);

Parameters

stylesheet [out, retval]
The node that represents an XSL style sheet. This must be a free-threaded document object.

C/C++ Return Values

E_FAIL
The value returned if the document is not a valid style sheet or if the document is free-threaded.

Remarks

The style sheet document is made read-only while the style sheet belongs to the template or any associated processor. The read-only flag is removed when the style sheet is released from all templates and processors.

Because the processors created by this template take a snapshot of the current style sheet and always use it, they are not affected by changes to the stylesheet property. The only way to update the processor to the new style sheet is to create a new processor.

See Also

Applies to: IXSLProcessor


stylesheet Property (IXSLTemplate)

Returns the Extensible Stylesheet Language (XSL) style sheet to compile into an XSL template.

[Script]

Script Syntax

var objXMLDOMNode = objXSLTemplate.stylesheet;
objXSLTemplate.stylesheet = objXMLDOMNode;

Example

var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xslProc;
xslDoc.async = false;
xslDoc.load("sample2.xsl");
xslt.stylesheet = xslDoc;
alert(xslt.stylesheet.xml);

File Name: Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = objXSLTemplate.stylesheet
objXSLTemplate.stylesheet = objXMLDOMNode

Example

Dim xslt As New Msxml2.XSLTemplate
Dim xslDoc As New Msxml2.FreeThreadedDOMDocument
Dim xslProc As IXSLProcessor
xslDoc.async = False
xslDoc.Load "sample2.xsl"
Set xslt.stylesheet = xslDoc
MsgBox xslt.stylesheet.xml

File Name: Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[C/C++]

C/C++ Syntax

HRESULT get_stylesheet(IXMLDOMNode** stylesheet);
HRESULT putref_stylesheet(IXMLDOMNode* stylesheet);

Parameters

stylesheet [out, retval][in]
The node that represents an XSL Transformations (XSLT) style sheet. This must be a free-threaded document object.

C/C++ Return Values

E_FAIL
The value returned if the document is not a valid style sheet or if the document is not free-threaded.

Remarks

The style sheet document is made read-only while the style sheet belongs to the template or any associated processor. The read-only flag is removed when the style sheet is released from all templates and processors.

Because the processors created by this template take a snapshot of the current style sheet and always use it, they are not affected by changes to this stylesheet property. The only way to update the processor to the new style sheet is to create a new processor.

See Also

Applies to: IXSLTemplate


systemId Property (IXMLDOMEntity)

Contains the system identifier associated with the entity.

[Script]

Script Syntax

strValue = oXMLDOMEntity.systemId;
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMEntity.systemId
[C/C++]

C/C++ Syntax

HRESULT get_systemId(
    BSTR *systemID);

Parameters

systemID [out, retval]
The system identifier associated with the entity, if specified. If the system identifier is not specified, contains the empty string.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned when no system ID is specified.
E_INVALIDARG
The value returned if systemID is Null.

Example

IXMLDOMEntity *pIXMLDOMEntity = NULL;
VARIANT varName ;
HRESULT hr;

try
{
   // See help on IXMLDOMEntity::get_notationName method for definition of
   // the GetFirstEntity() method.
   pIXMLDOMEntity = GetFirstEntity();

   if(pIXMLDOMEntity)
   {
      hr = pIXMLDOMEntity->get_systemId(&varName);
      if(SUCCEEDED(hr))
         ::MessageBox(NULL, _bstr_t(varName), _T("Public ID"), MB_OK);
      pIXMLDOMEntity->Release();
   }
}
catch(...)
{
   if(pIXMLDOMEntity)
      pIXMLDOMEntity->Release();
   DisplayErrorToUser();
}

Remarks

String. The property is read-only. If the system identifier is not specified, the property contains the empty string.

See Also

Applies to: IXMLDOMEntity


systemId Property (IXMLDOMNotation)

Contains the system identifier for the notation.

[Script]

Script Syntax

strValue = oXMLDOMNotation.systemId;
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMNotation.systemId
[C/C++]

C/C++ Syntax

HRESULT get_systemId(
    VARIANT *systemID);

Parameters

systemID [out, retval]
The system identifier for the notation. If the system identifier is not specified, this contains an empty string.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if systemID is Null.

Remarks

Variant. The property is read-only. If the system identifier is not specified, this contains the empty string.

See Also

Applies to: IXMLDOMNotation


tagName Property

Contains the element name.

[Script]

Script Syntax

strValue = oXMLDOMElement.tagName;

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeBook, namedNodeMap;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodeBook = xmlDoc.selectSingleNode("//book");
alert(nodeBook.tagName);
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMElement.tagName

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeBook As IXMLDOMElement
Dim namedNodeMap As IXMLDOMNamedNodeMap
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodeBook = xmlDoc.selectSingleNode("//book")
MsgBox nodeBook.tagName
[C/C++]

C/C++ Syntax

HRESULT get_tagName(
    BSTR *tagName);

Parameters

tagName [out, retval]
The string that represents the element's name.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value when returning Null.
E_INVALIDARG
The value returned if tagName is Null.

Example

IXMLDOMElement *pIXMLDOMElement = NULL;
BSTR bstrTagName = NULL;
IXMLDOMDocument *pIXMLDOMDocument = NULL;
HRESULT hr;

try
{
   // Create an instance of DOMDocument and initialize pIXMLDOMDocument.
   // Load/create an XML fragment.
   hr = pIXMLDOMDocument->get_documentElement(&pIXMLDOMElement);
   SUCCEEDED(hr) ? 0 : throw hr;

   if(pIXMLDOMElement)
   {
      hr = pIXMLDOMElement->get_tagName(&bstrTagName);
      if(SUCCEEDED(hr))
      {
         ::MessageBox(NULL, bstrTagName, _T("Tag Name"), MB_OK);
      }
      ::SysFreeString(bstrTagName);
      bstrTagName = NULL;
      pIXMLDOMElement->Release();
   }
}
catch(...)
{
   if(bstrTagName)
      ::SysFreeString(bstrTagName);
   if(pIXMLDOMElement)
      pIXMLDOMElement->Release();
   DisplayErrorToUser();
}

Remarks

String. The property is read-only. It contains the string that represents the element's name. For example, the tag name in the following tag is "book".

<book ISBN="1572318546">

See Also

Applies to: IXMLDOMElement


target Property

Specifies the target for the processing instruction.

[Script]

Script Syntax

strValue = oXMLDOMProcessingInstruction.target;

Example

The following script example iterates through the document's child nodes. If it finds a node of type NODE_PROCESSING_INSTRUCTION (7), it displays the node's target.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var pi;
xmlDoc.async = false;
xmlDoc.load("books.xml");
for (var i=0; i<xmlDoc.childNodes.length; i++) {
  if (xmlDoc.childNodes.item(i).nodeType == 7) {
    pi = xmlDoc.childNodes.item(i);
    alert(pi.target);
  }
}
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMProcessingInstruction.target

Example

The following Microsoft® Visual Basic® example iterates through the document's child nodes. If it finds a node of type NODE_PROCESSING_INSTRUCTION (7), it displays the node's target.

Dim xmlDoc As New Msxml2.DOMDocument
Dim pi As IXMLDOMProcessingInstruction
xmlDoc.Load ("books.xml")
For i = 0 To (xmlDoc.childNodes.length - 1)
  If xmlDoc.childNodes.Item(i).nodeType = NODE_PROCESSING_INSTRUCTION Then
    Set pi = xmlDoc.childNodes.Item(i)
    MsgBox pi.Target
  End If
Next
[C/C++]

C/C++ Syntax

HRESULT get_target(
    BSTR *name);

Parameters

name [out, retval]
The application to which this processing instruction is directed (the target).

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

String. The property is read-only. XML defines the target as the first token following the markup that begins the processing instruction. For example, the target has the value "xml" in the processing instruction <?xml version="1.0">.

The target property has the same value as the nodeName property.

See Also

nodeName Property

Applies to: IXMLDOMProcessingInstruction


text Property

Represents the text content of the node or the concatenated text representing the node and its descendants.

[Script]

Script Syntax

strValue = oXMLDOMNode.text;

Example

The following script example creates an IXMLDOMNode of type NODE_ENTITY, and then displays the object's text value, including that of any of the object's child nodes.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var currNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
currNode = xmlDoc.documentElement.childNodes.item(0);
alert(currNode.text);
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMNode.text

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNode of type NODE_ENTITY, and then displays the object's text value, including that of any of the object's child nodes.

Dim xmlDoc As New Msxml2.DOMDocument
Dim currNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set currNode = xmlDoc.documentElement.childNodes.Item(0)
MsgBox currNode.Text
[C/C++]

C/C++ Syntax

HRESULT get_text(
    BSTR *text);

Parameters

text [out, retval]
A string representing the text content of this node and its descendants. This value varies depending on the value of the nodeType method.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned when there is no text.
E_INVALIDARG
The value returned if text is Null.

Remarks

String. The property is read/write. When concatenated, the text represents the contents of text or CDATA nodes. All concatenated text nodes are normalized according to xml:space attributes and the value of the preserveWhiteSpace switch. Concatenated CDATA text is not normalized. (Child nodes that contain NODE_COMMENT and NODE_PROCESSING_INSTRUCTION nodes are not concatenated.) .text trims the whitespace on the edges of the result, and "normalizes" \r\n => \n, but otherwise just concatenates text.

Retrieves and sets the string representing the text contents of this node or the concatenated text representing this node and its descendants.

For more precise control over text manipulation in an XML document, use the lower-level nodeValue property, which returns the raw text associated with a NODE_TEXT node.

Consider the root element in this example.

<root att="   123   a   <   ">
   <a>   a   a   </a>
   <!--   comment   b   -->
   <?pi   pi   c   ?>
   <![CDATA[   cdata   d   ]]>
   e   f
</root>

The text property for the root element returns the following concatenated text.

"a a   cdata   d    e f"

Note that the white space within the CDATA node is preserved.

This value depends on the value of the nodeType property.

NODE_ATTRIBUTE, NODE_DOCUMENT, NODE_ENTITY | Returns a string representing the value of the node. This is the concatenated text of all subnodes with entities expanded.
NODE_CDATA_SECTION, NODE_COMMENT, NODE_PROCESSING_INSTRUCTION, NODE_TEXT | Returns the text contained in the node, which is the same as the nodeValue property.
NODE_DOCUMENT_TYPE, NODE_NOTATION | Returns the empty string (""). These node types do not have associated text.
NODE_DOCUMENT_FRAGMENT | Returns the text comprised of the concatenation of all descendant nodes.
NODE_ELEMENT Contains a string that represents the element content. This will also include the text content from all child elements, concatenated in document order. For example, consider the following XML.
<count>
  <item>one</item>
  <item>two</item>
  <item>three</item>
  <item>four</item>
</count>

The text property for the <count> element contains the value "one two three four".
NODE_ENTITY_REFERENCE | Returns the string representation of the entity reference.

See Also

nodeType Property | nodeValue Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


url Property (DOMDocument)

Returns the URL for the last loaded XML document.

[Script]

Script Syntax

var objurl = objXMLDOMDocument.url;

Example

The following script example creates a DOMDocument and displays the value of its url property.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
alert(xmlDoc.url);
[Visual Basic]

Visual Basic Syntax

Set objurl = objXMLDOMDocument.url

Example

The following Microsoft® Visual Basic® example creates a DOMDocument and displays the value of its url property.

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.async = False
xmlDoc.Load ("books.xml")
MsgBox xmlDoc.URL
[C/C++]

C/C++ Syntax

HRESULT get_url(
    BSTR *urlString);

Parameters

urlString [out, retval]
The URL from the last successful load. If the document is being built in memory, this property returns Null.

C/C++ Return Values

S_OK
Value returned if successful.
S_FALSE
Value returned if there is no URL.
E_INVALIDARG
Value returned if urlString is Null.

Remarks

String. The property is read-only. It returns the URL from the last successful load. If the document is being built in memory, this property returns Null.

The url property is not updated after saving a document with the save method. To update the url property, reload the document using the load method.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

load Method | save Method

Applies to: DOMDocument


url Property (IXMLDOMParseError)

Contains the URL of the XML document containing the last error.

[Script]

Script Syntax

strValue = oXMLDOMParseError.url;

Example

The following script example attempts to load an XML document. If it encounters a parse error, it displays the URL of the document containing the error.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
if (xmlDoc.parseError.errorCode != 0) {
   alert(xmlDoc.parseError.url);
} else {
  alert(xmlDoc.documentElement.xml);
}
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMParseError.url

Example

The following Microsoft® Visual Basic® example attempts to load an XML document. If it encounters a parse error, it displays the URL of the document containing the error.

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.async = False
xmlDoc.Load ("books.xml")
If xmlDoc.parseError.errorCode <> 0 Then
   MsgBox xmlDoc.parseError.URL
Else
  MsgBox xmlDoc.documentElement.xml
End If
[C/C++]

C/C++ Syntax

HRESULT get_url(
    BSTR *urlString);

Parameters

urlString [out, retval]
The URL of the XML file containing the error.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned if no error occurred.

Remarks

String. The property is read-only.

See Also

Applies to: IXMLDOMParseError


validateOnParse Property

Indicates whether the parser should validate this document.

[Script]

Script Syntax

boolValue = oXMLDOMDocument.validateOnParse;
objXMLDOMDocument.validateOnParse = boolValue;

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.validateOnParse = true;
xmlDoc.load("books.xml");
[Visual Basic]

Visual Basic Syntax

boolValue = oXMLDOMDocument.validateOnParse
objXMLDOMDocument.validateOnParse = boolValue

Example

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.async = False
xmlDoc.validateOnParse = True
xmlDoc.Load "books.xml"
[C/C++]

C/C++ Syntax

HRESULT get_validateOnParse(
    VARIANT_BOOL *isValidating);
HRESULT put_validateOnParse(
    VARIANT_BOOL isValidating);

Parameters

isValidating [out, retval][in]
If True, validates during parsing. If False, parses only for well-formed XML.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG (for get_validateOnParse only)
The value returned if isValidating is Null.

Remarks

Boolean. The property is read/write. If True, it validates during parsing. If False, it parses only for well-formed XML. The default is True.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

Applies to: DOMDocument


value Property

Contains the attribute value.

[Script]

Script Syntax

objValue = oXMLDOMAttribute.value;
objXMLDOMAttribute.value = objValue;

Example

The following script example gets the value of the first attribute of the document root and assigns it to the variable myVar.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var myVar;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
myVar = root.firstChild.attributes.item(0).value;
alert(myVar);
[Visual Basic]

Visual Basic Syntax

objValue = oXMLDOMAttribute.value
objXMLDOMAttribute.value = objValue

Example

The following Microsoft® Visual Basic® example gets the value of the first attribute of the document root and assigns it to the variable myVar.

Dim xmlDoc As New Msxml2.DOMDocument
Dim myVar As Variant
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
myVar = root.firstChild.Attributes.Item(0).Value
MsgBox myVar
[C/C++]

C/C++ Syntax

HRESULT get_value(
    VARIANT *attributeValue);
HRESULT put_value(
    VARIANT *attributeValue);

Parameters

attributeValue [out, retval][in]
The value of the attribute. For attributes with subnodes, the string is the concatenated text of all subnodes with character and general entity reference expanded (replaced with their values).

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG (for get_value only)
The value returned if attributeValue is Null.
E_FAIL (for put_value only)
The value returned if an error occurs.

Remarks

Variant. The property is read/write. It returns the value of the attribute. For attributes with subnodes, the string is the concatenated text of all subnodes with character and general entity references expanded (replaced with their values).

The new attribute value is added as the value of a single text node that is a child of the attribute node. The string contents are unparsed.

See Also

Applies to: IXMLDOMAttribute


xml Property

Contains the XML representation of the node and all its descendants.

[Script]

Script Syntax

strValue = oXMLDOMNode.xml;

Example

The following script example creates an IXMLDOMNode of type NODE_ENTITY, and then displays the object's XML value, including that of any of the object's child nodes.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var currNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
currNode = xmlDoc.documentElement.childNodes.item(0);
alert(currNode.xml);
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMNode.xml

Example

The following Microsoft Visual Basic® example creates an IXMLDOMNode of type NODE_ENTITY, and then displays the object's XML value, including that of any of the object's child nodes.

Dim xmlDoc As New Msxml2.DOMDocument
Dim currNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set currNode = xmlDoc.documentElement.childNodes.Item(0)
MsgBox currNode.xml
[C/C++]

C/C++ Syntax

HRESULT get_xml(
    BSTR *xmlString);

Parameters

xmlString [out, retval]
An XML representation of this node and all its descendants.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if xmlString is Null.

Remarks

The property is read-only.

The xml property always returns a Unicode string. That is, the xml property for DOMDocument converts the document from its original encoding to Unicode. As a result, the original encoding attribute is removed. For example, <?xml version="1.0" encoding="UTF-8"?> appears in the xml property as follows.

<?xml version="1.0"?>

If the original encoding was not removed by the xml property, the following line returns an error indicating the parser cannot switch from Unicode to UTF-8 encoding.

xmlDoc.loadxml(xmlDoc.xml);

If you use the save method, the original encoding is preserved. For example, if you load a document in Microsoft® Windows® 1252 encoding, it will be saved in that format.

This value depends on the value of the nodeType property.

NODE_ATTRIBUTE, NODE_CDATA_SECTION, NODE_COMMENT, NODE_DOCUMENT, NODE_ELEMENT, NODE_ENTITY, NODE_NOTATION, NODE_PROCESSING_INSTRUCTION, NODE_TEXT | Returns the string representation of the node and all its descendants.
NODE_DOCUMENT_FRAGMENT | Returns the string representation of all descendant nodes of the document fragment.
NODE_DOCUMENT_TYPE | Returns the string representation of the <!DOCTYPE ...> declaration, including the internal subset if specified.
NODE_ENTITY_REFERENCE | Returns the string representation of the entity reference. Although the entity reference has children, they are not returned.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

nodeType Property | save method | XML DOM Persistence

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


XML DOM Methods

This section includes the following topics.

  • abort Method (DOMDocument)
  • abort Method (IXMLHTTPRequest)
  • abort Method (ServerXMLHTTP/IServerXMLHTTPRequest)
  • absoluteChildNumber Method
  • add Method
  • addCollection Method
  • addObject Method
  • addParameter Method
  • ancestorChildNumber Method
  • appendChild Method
  • appendData Method
  • childNumber Method
  • clone Method
  • cloneNode Method
  • createAttribute Method
  • createCDATASection Method
  • createComment Method
  • createDocumentFragment Method
  • createElement Method
  • createEntityReference Method
  • createNode Method
  • createProcessingInstruction Method
  • createProcessor Method
  • createTextNode Method
  • deleteData Method
  • depth Method
  • formatDate Method
  • formatIndex Method
  • formatNumber Method
  • formatTime Method
  • get Method
  • getAllResponseHeaders Method (IXMLHTTPRequest)
  • getAllResponseHeaders Method (ServerXMLHTTP/IServerXMLHTTPRequest)
  • getAttribute Method
  • getAttributeNode Method
  • getElementsByTagName Method (DOMDocument)
  • getElementsByTagName Method (IXMLDOMElement)
  • getNamedItem Method
  • getOption(ServerXMLHTTP/IServerXMLHTTPRequest)
  • getProperty Method (IXMLDOMDocument2)
  • getProperty Method (IXMLDOMSelection)
  • getQualifiedItem Method
  • getResponseHeader Method (IXMLHTTPRequest)
  • getResponseHeader Method (ServerXMLHTTP/IServerXMLHTTPRequest)
  • hasChildNodes Method
  • hasFeature Method
  • insertBefore Method
  • insertData Method
  • item Method (IXMLDOMNodeList)
  • item Method (IXMLDOMNamedNodeMap)
  • load Method
  • loadXML Method
  • matches Method
  • nextNode Method (IXMLDOMNodeList)
  • nextNode Method (IXMLDOMNamedNodeMap)
  • nodeFromID Method
  • normalize Method
  • open Method (IXMLHTTPRequest)
  • open Method (ServerXMLHTTP/IServerXMLHTTPRequest)
  • peekNode Method
  • remove Method
  • removeAll Method
  • removeAttribute Method
  • removeAttributeNode Method
  • removeChild Method
  • removeNamedItem Method
  • removeNext Method
  • removeQualifiedItem Method
  • replaceChild Method
  • replaceData Method
  • reset Method (IXMLDOMNamedNodeMap)
  • reset Method (IXMLDOMNodeList)
  • reset Method (IXSLProcessor)
  • save Method
  • selectNodes Method
  • selectSingleNode Method
  • send Method (IXMLHTTPRequest)
  • send Method (ServerXMLHTTP/IServerXMLHTTPRequest)
  • setAttribute Method
  • setAttributeNode Method
  • setNamedItem Method
  • setOption(ServerXMLHTTP/IServerXMLHTTPRequest)
  • setProperty Method
  • setRequestHeader Method (IXMLHTTPRequest)
  • setRequestHeader Method (ServerXMLHTTP/IServerXMLHTTPRequest)
  • setStartMode Method
  • setTimeouts Method
  • splitText Method
  • substringData Method
  • transform Method
  • transformNode Method
  • transformNodeToObject Method
  • uniqueID Method
  • validate Method
  • waitForResponse Method


abort Method (DOMDocument)

Aborts an asynchronous download in progress.

[Script]

Script Syntax

oXMLDOMDocument.abort();

Example

var xmlDOM;
xmlDOM = new ActiveXObject("Msxml2.DOMDocument");
xmlDOM.async = true;
xmlDOM.onreadystatechange = doOnReadyStateChange;
xmlDOM.load("books.xml");

function doOnReadyStateChange () {
   if (xmlDOM.readyState == 1) {
      xmlDOM.abort();
   }
}
[Visual Basic]

Visual Basic Syntax

oXMLDOMDocument.abort

Example

Dim WithEvents xmlDOM As Msxml2.DOMDocument
Private Sub cmddoAbortDOMDocument_Click()
    Set xmlDOM = New Msxml2.DOMDocument
    xmlDOM.async = True
    xmlDOM.Load "books.xml"
End Sub
Private Sub xmlDOM_onreadystatechange()
    If xmlDOM.readyState = 1 Then
        xmlDOM.abort
    End If
End Sub
[C/C++]

C/C++ Syntax

HRESULT abort(
    void
);

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

This method stops download and parsing and discards any portion of the XML tree already built. IXMLDOMParseError indicates that the download was stopped.

If the readyState property has the value "COMPLETED", no action is taken and the current document is unchanged.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

IXMLDOMParseError | readyState Property (DOMDocument)

Applies to: DOMDocument


abort Method (IXMLHTTPRequest)

Cancels the current HTTP request.

[Script]

Script Syntax

oXMLHttpRequest.abort();

Example

var xmlhttp;
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp.onreadystatechange = doHttpReadyStateChange;
xmlhttp.open("GET", "http://localhost/sample.xml", true);
xmlhttp.send();

function doHttpReadyStateChange() {
   if (xmlhttp.readyState == 2) {
      xmlhttp.abort();
   }
}
[Visual Basic]

Visual Basic Syntax

oXMLHttpRequest.abort
[C/C++]

C/C++ Syntax

HRESULT abort(void);

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

The request will be returned to the UNINITIALIZED state, and open method must be called next.

See Also

readyState Property (IXMLHTTPRequest) | open Method (IXMLHTTPRequest)

Applies to: IXMLHTTPRequest


abort Method (ServerXMLHTTP/IServerXMLHTTPRequest)

Cancels the current HTTP request.

[Script]

Script Syntax

oServerXMLHttpRequest.abort();

Example

var xmlServerHttp;
xmlServerHttp = new ActiveXObject("Msxml2.ServerXMLHTTP");
xmlServerHttp.onreadystatechange = doServerHttpReadyStateChange;
xmlServerHttp.open("GET", "http://localhost/sample.xml", true);
xmlServerHttp.send();

function doServerHttpReadyStateChange() {
   if (xmlServerHttp.readyState == 2) {
      xmlServerHttp.abort();
   }
}
[Visual Basic]

Visual Basic Syntax

oServerXMLHttpRequest.abort
[C/C++]

C/C++ Syntax

HRESULT abort(void);

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

The object will be returned to the UNINITIALIZED state, and open method must be called next.

See Also

readyState Property (ServerXMLHTTP/IServerXMLHTTPRequest) | open Method (ServerXMLHTTP/IServerXMLHTTPRequest)

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


absoluteChildNumber Method

Returns the number of the node that is relative to all siblings.

[Script]

Script Syntax

lValue = oXTLRuntime.absoluteChildNumber(pNode);

Parameters

pNode
The object. The node to which the child number is to be returned.

Return Value

A long integer. Returns the index for the node in its parent's list of all child nodes. The first entry in the list is assigned the value "1".

[Visual Basic]

Visual Basic Syntax

lValue = oXTLRuntime.absoluteChildNumber(pNode)

Parameters

pNode
The object. The node to which the child number is to be returned.

Return Value

A long integer. Returns the index for the node in its parent's list of all child nodes. The first entry in the list is assigned the value "1".

[C/C++]

C/C++ Syntax

HRESULT absoluteChildNumber(IXMLDOMNode* pNode, long* pNumber);

Parameters

pNode [in]
The node for which the child number is to be returned.
pNumber [out, retval]
The index for the node in its parent's list of all child nodes. The first entry in the list is assigned the value "1".

C/C++ Return Values

Returns S_OK if successful, or an error code otherwise.

See Also

Applies to: IXTLRuntime


add Method

Adds a new schema to the schema collection and associates the given namespace URI with the specified schema.

[Script]

Script Syntax

objXMLDOMSchemaCol.add(namespaceURI, var);

Parameters

namespaceURI
The namespace to associate with the specified schema. The empty string, "", will associate the schema with the empty namespace, xmlns="".

This may be any string that can be used in an xmlns attribute, but it cannot contain entity references. The same white space normalization that occurs on the xmlns attribute also occurs on namespaceURI (that is, leading and trailing white space is trimmed, new lines are converted to spaces, and multiple adjacent white space characters are collapsed into one space).

var
This specifies the schema to load. It will load it synchronously and with resolveExternals=false and validateOnParse=false. The schema parameter can also be any DOMDocument.

This argument can be Null, which results in the removal of any schema for the specified namespaces. If the schema is an IXMLDOMNode, the entire document the node belongs to will be preserved.

Example

The following script example attaches a schema to an XML document.

var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var SchemaCache;
// Create the collection.
SchemaCache = new ActiveXObject("Msxml2.XMLSchemaCache");
SchemaCache.add("x-schema:books.xml", "d:\\inetpub\\wwwroot\\bookschema.xml");
// This Schema Cache can be attached to multiple documents.
xslDoc.schemas = SchemaCache;
xslDoc.async = false;
// The document will load only if a valid schema is attached to the xml
// file.
xmlDoc.load("http://sampleserver/samplexmldtd.xml");
alert(xslDoc.xml);

http://sampleserver/samplexmldtd.xml

<?xml version='1.0'?>
<COLLECTION xmlns="x-schema:books.xml"
   xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
   <BOOK>
      <TITLE>Cosmos</TITLE>
      <AUTHOR>Carl Sagan</AUTHOR>
      <PUBLISHER>Ballantine Books</PUBLISHER>
   </BOOK>
   <BOOK>
      <TITLE>Catwings</TITLE>
      <AUTHOR>Ursula K. Le Guin</AUTHOR>
      <PUBLISHER>Scholastic</PUBLISHER>
   </BOOK>
</COLLECTION>

d:\inetpub\wwwroot\bookschema.xml

<?xml version="1.0"?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data">
   <ElementType name="TITLE" />
   <ElementType name="AUTHOR" />
   <ElementType name="PUBLISHER" />
   <ElementType name="DATE" />
   <ElementType name="BOOK">
      <element type="TITLE" />
      <element type="AUTHOR" />
      <element type="PUBLISHER" />
   </ElementType>
   <ElementType name="COLLECTION">
      <element type="DATE"/>
      <element type="BOOK" />
   </ElementType>
</Schema>

Output (in a message box)

<?xml version='1.0'?>
<COLLECTION xmlns="x-schema:books.xml"
   xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
   <BOOK>
      <TITLE>Cosmos</TITLE>
      <AUTHOR>Carl Sagan</AUTHOR>
      <PUBLISHER>Ballantine Books</PUBLISHER>
   </BOOK>
   <BOOK>
      <TITLE>Catwings</TITLE>
      <AUTHOR>Ursula K. Le Guin</AUTHOR>
      <PUBLISHER>Scholastic</PUBLISHER>
   </BOOK>
</COLLECTION>
[Visual Basic]

Visual Basic Syntax

objXMLDOMSchemaCol.add(namespaceURI, var)

Parameters

namespaceURI
This is the namespace to associate with the specified schema. The empty string, "", will associate the schema with the empty namespace, xmlns="".

This may be any string that can be used in an xmlns attribute, but it cannot contain entity references. The same white space normalization that occurs on the xmlns attribute also occurs on namespaceURI (that is, leading and trailing white space is trimmed, new lines are converted to spaces, and multiple adjacent white space characters are collapsed into one space).

var
Specifies the schema to load. It will load it synchronously and with resolveExternals=false and validateOnParse=false. The schema parameter can also be any DOMDocument.

This argument can be Null, which results in the removal of any schema for the specified namespaces. If the schema is an IXMLDOMNode, the entire document the node belongs to will be preserved.

Example

The following Visual Basic example attaches a schema to an XML document.

Dim xslDoc As New Msxml2.FreeThreadedDOMDocument
Dim SchemaCache
'Create the collection.
Set SchemaCache = CreateObject("Msxml2.XMLSchemaCache")
SchemaCache.Add "x-schema:books.xml", "d:\inetpub\wwwroot\bookschema.xml"
'This Schema Cache can be attached to multiple documents.
Set xslDoc.schemas = SchemaCache
xslDoc.async = False
'The document will load only if a valid schema is attached to the xml
'file.
xslDoc.Load "http://sampleserver/samplexmldtd.xml"
MsgBox xslDoc.xml

File Name: http://sampleserver/samplexmldtd.xml

<?xml version='1.0'?>
<COLLECTION xmlns="x-schema:books.xml"
   xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
   <BOOK>
      <TITLE>Cosmos</TITLE>
      <AUTHOR>Carl Sagan</AUTHOR>
      <PUBLISHER>Ballantine Books</PUBLISHER>
   </BOOK>
   <BOOK>
      <TITLE>Catwings</TITLE>
      <AUTHOR>Ursula K. Le Guin</AUTHOR>
      <PUBLISHER>Scholastic</PUBLISHER>
   </BOOK>
</COLLECTION>

File Name: d:\inetpub\wwwroot\bookschema.xml

<?xml version="1.0"?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data">
   <ElementType name="TITLE"/>
   <ElementType name="AUTHOR"/>
   <ElementType name="PUBLISHER"/>
   <ElementType name="DATE"/>
   <ElementType name="BOOK" model="closed">
      <element type="TITLE"/>
      <element type="AUTHOR"/>
      <element type="PUBLISHER"/>
   </ElementType>
   <ElementType name="COLLECTION" model="closed">
      <element type="DATE"/>
      <element type="BOOK"/>
   </ElementType>
</Schema>

Output (in a message box)

<?xml version='1.0'?>
<COLLECTION xmlns="x-schema:books.xml"
   xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
   <BOOK>
      <TITLE>Cosmos</TITLE>
      <AUTHOR>Carl Sagan</AUTHOR>
      <PUBLISHER>Ballantine Books</PUBLISHER>
   </BOOK>
   <BOOK>
      <TITLE>Catwings</TITLE>
      <AUTHOR>Ursula K. Le Guin</AUTHOR>
      <PUBLISHER>Scholastic</PUBLISHER>
   </BOOK>
</COLLECTION>
[C/C++]

C/C++ Syntax

HRESULT add(BSTR namespaceURI, VARIANT var);

Parameters

namespaceURI [in]
The namespace to associate with the specified schema.

The empty string, "", will associate the schema with the empty namespace, xmlns="". This may be any string that can be used in an xmlns attribute, but it cannot contain entity references. The same white space normalization that occurs on the xmlns attribute also occurs on this parameter (that is, leading and trailing white space is trimmed, new lines are converted to spaces, and multiple adjacent white space characters are collapsed into one space).

var [in]
This specifies the schema. It can be a BSTR, in which case it points to the URL to load. It will load it synchronously and with resolveExternals=false and validateOnParse=false. var can also be any DOMDocument.

This argument can be Null, which results in the removal of any schema for the specified namespaces. If the schema is an IXMLDOMNode, the entire document the node belongs to will be preserved.

C/C++ Return Values

If this call fails, the collection remains unchanged. E_FAIL is returned if:

  • the collection is read-only.
  • the document is not a recognized schema.
  • an error occurs when compiling the schema.
  • the ready state of the document is not 4.

If it was loading a schema and encountered a parse error, then the parse error reason is returned in the IErrorInfo. If the VARIANT argument contains an invalid value, E_INVALIDARG is returned.

Example

#import "msxml3.dll"
using namespace Msxml2;

#define CHECK_AND_RELEASE(pInterface)  \
if(pInterface) \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

#define RELEASE(pInterface)  \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

BOOL DOMDocument2schemas()
{
   BOOL bResult = FALSE;
   short sResult = FALSE;
   IXMLDOMNodeList *pIXMLDOMNodeList=NULL;
   IXMLDOMDocument2 *pIXMLDOMDocument2=NULL;
   IXMLDOMSchemaCollection *pIXMLDOMSchemaCollection=NULL;
   HRESULT hr;
   BSTR bstrValue;
   VARIANT varValue;

   try
   {
      hr=CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_SERVER,
         IID_IXMLDOMDocument2, (LPVOID*)(&pIXMLDOMDocument2));
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXMLDOMDocument2)
      {
         hr=pIXMLDOMDocument2->put_async(VARIANT_FALSE);
         if(SUCCEEDED(hr))
         {
            hr=CoCreateInstance(CLSID_XMLSchemaCache, NULL, CLSCTX_SERVER,
               IID_IXMLDOMSchemaCollection,
               (LPVOID*)(&pIXMLDOMSchemaCollection));
            SUCCEEDED(hr) ? 0 : throw hr;

            if(SUCCEEDED(hr) && pIXMLDOMSchemaCollection)
            {
               hr = pIXMLDOMSchemaCollection->add(_T("x-schema:books"),
                  _variant_t(_T("d:\\inetpub\\wwwroot\\bookschema.xml")));
               if(SUCCEEDED(hr))
               {
                  varValue.vt = VT_DISPATCH;
                  varValue.pdispVal = pIXMLDOMSchemaCollection;
                  hr=pIXMLDOMDocument2->putref_schemas(varValue);

               // The document will load only if a valid schema is
               // attached to the xml file.
                  hr=pIXMLDOMDocument2->load(_variant_t(
                  _T("d:\\inetpub\\wwwroot\\samplexmldtd.xml")),
                  &sResult);
                  if(SUCCEEDED(hr) && (sResult==VARIANT_TRUE))
                  {
                     pIXMLDOMDocument2->get_xml(&bstrValue);
                     ::MessageBox(NULL, bstrValue, _T("Loaded Document"),
                        MB_OK);
                     bResult=TRUE;
                  }
               }
               RELEASE(pIXMLDOMSchemaCollection);
            }
         }
         RELEASE(pIXMLDOMDocument2);
      }
   }
   catch(...)
   {
      CHECK_AND_RELEASE(pIXMLDOMDocument2);
      CHECK_AND_RELEASE(pIXMLDOMNodeList);
      CHECK_AND_RELEASE(pIXMLDOMSchemaCollection);
      DisplayErrorToUser();
   }
   return bResult;
}

File Name: d:\\inetpub\\wwwroot\\samplexmldtd.xml

<?xml version='1.0'?>
<COLLECTION xmlns="x-schema:books"
   xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
  <BOOK>
    <TITLE>Cosmos</TITLE>
    <AUTHOR>Carl Sagan</AUTHOR>
    <PUBLISHER>Ballantine Books</PUBLISHER>
  </BOOK>
  <BOOK>
    <TITLE>Catwings</TITLE>
    <AUTHOR>Ursula K. Le Guin</AUTHOR>
    <PUBLISHER>Scholastic</PUBLISHER>
  </BOOK>
  <BOOK>
    <TITLE>Home Town</TITLE>
    <AUTHOR>Tracy Kidder</AUTHOR>
    <PUBLISHER>Random House</PUBLISHER>
  </BOOK>
</COLLECTION>

File Name: d:\\inetpub\\wwwroot\\bookschema.xml

<?xml version="1.0"?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data">
   <ElementType name="TITLE" />
   <ElementType name="AUTHOR" />
   <ElementType name="PUBLISHER" />
   <ElementType name="DATE" />
   <ElementType name="BOOK" model="closed">
      <element type="TITLE" />
      <element type="AUTHOR" />
      <element type="PUBLISHER" />
   </ElementType>
   <ElementType name="COLLECTION" model="closed">
      <element type="BOOK" />
   </ElementType>
</Schema>

Remarks

Schemas referenced by this schema are not added to the collection. The contents of the schema are added to the internal collection. (The schema can be copied.). If a schema is already in the collection with this namespace, it will be replaced by the new one.

See Also

Applies to: IXMLDOMSchemaCollection/XMLSchemaCache


addCollection Method

Adds schemas from another collection into the current collection and replaces any schemas that collide on the same namespace URI.

[Script]

Script Syntax

objXMLDOMSchemaCol.addCollection(objXMLDOMSchemaCollection);

Parameters

objXMLDOMSchemaCollection
The collection containing the schemas to add.

Example

var xmldoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xsldoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var SchemaCache = new ActiveXObject("Msxml2.XMLSchemaCache");
var SchemaCache2 = new ActiveXObject("Msxml2.XMLSchemaCache");

xmldoc.loadXML("<root><bar>bar</bar></root>");
xsldoc.async = false;
xsldoc.validateOnParse = false;
SchemaCache.add("x-schema:books", "d:\\inetpub\\wwwroot\\bookschema.xml");
SchemaCache2.addCollection(SchemaCache);
SchemaCache2.add("x-schema:books", "d:\\inetpub\\wwwroot\\newbookschema.xml");
xsldoc.schemas = SchemaCache2;
// The document will load only if a valid schema is attached to the xml
// file.

xsldoc.load("d:\\inetpub\\wwwroot\\samplexmldtd.xml");

alert(xsldoc.xml) ;

File Name: d:\inetpub\wwwroot\samplexmldtd.xml

<?xml version='1.0'?>
<COLLECTION xmlns="x-schema:books"
   xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
   <BOOK>
      <TITLE>Cosmos</TITLE>
      <AUTHOR>Carl Sagan</AUTHOR>
      <PUBLISHER>Ballantine Books</PUBLISHER>
   </BOOK>
</COLLECTION>

Output (in a message box)

<?xml version='1.0'?>
<COLLECTION xmlns="x-schema:books"
   xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
   <BOOK>
      <TITLE>Cosmos</TITLE>
      <AUTHOR>Carl Sagan</AUTHOR>
      <PUBLISHER>Ballantine Books</PUBLISHER>
   </BOOK>
</COLLECTION>
[Visual Basic]

Visual Basic Syntax

objXMLDOMSchemaCol.addCollection(objXMLDOMSchemaCollection)

Parameters

objXMLDOMSchemaCollection
The collection containing the schemas to add.

Example

Dim xmldoc As New Msxml2.FreeThreadedDOMDocument
Dim xsldoc As New Msxml2.FreeThreadedDOMDocument
Dim SchemaCache As New Msxml2.XMLSchemaCache
Dim SchemaCache2 As New Msxml2.XMLSchemaCache

xmldoc.loadXML "<root><bar>bar</bar></root>"

xsldoc.async = False
xsldoc.validateOnParse = False
SchemaCache.Add "x-schema:books", "d:\inetpub\wwwroot\bookschema.xml"
SchemaCache2.addCollection SchemaCache
SchemaCache2.Add "x-schema:books", "d:\inetpub\wwwroot\newbookschema.xml"
Set xsldoc.schemas = SchemaCache2
' The document will load only if a valid schema is attached to the xml
' file.

xsldoc.Load "d:\inetpub\wwwroot\samplexmldtd.xml"

MsgBox xsldoc.xml

File Name: d:\inetpub\wwwroot\samplexmldtd.xml

<?xml version='1.0'?>
<COLLECTION xmlns="x-schema:books"
   xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
   <BOOK>
      <TITLE>Cosmos</TITLE>
      <AUTHOR>Carl Sagan</AUTHOR>
      <PUBLISHER>Ballantine Books</PUBLISHER>
   </BOOK>
</COLLECTION>

Output (in a message box)

<?xml version='1.0'?>
<COLLECTION xmlns="x-schema:books"
   xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
   <BOOK>
      <TITLE>Cosmos</TITLE>
      <AUTHOR>Carl Sagan</AUTHOR>
      <PUBLISHER>Ballantine Books</PUBLISHER>
   </BOOK>
</COLLECTION>
[C/C++]

C/C++ Syntax

HRESULT addCollection(IXMLDOMSchemaCollection * otherCollection);

Parameters

otherCollection [in]
The collection containing the schemas to add.

C/C++ Return Values

S_OK
The value returned if the collection is added successfully.
E_FAIL is returned if:
  • the collection is read-only.
  • the document is not a recognized schema.
  • an error occurs when compiling the schema.
  • the ready state of the document is not 4.
E_POINTER
The value returned if input pointer is invalid.

Remarks

There is no guarantee that the two collections will return exactly the same schema. The collection is free to clone them, if necessary.

Adding a collection to itself has no effect.

See Also

Applies to: IXMLDOMSchemaCollection/XMLSchemaCache


addObject Method

Adds objects into a style sheet.

[Script]

Script Syntax

objXSLProcessor.addObject(obj, namespaceURI);

Parameters

obj
The object to pass in.
namespaceURI
The namespace to use inside the style sheet to identify the object.

Example

The following script example passes an object to the style sheet.

var xsldoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xmldoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xsltemp = new ActiveXObject("Msxml2.XSLTemplate");
var xslproc;

xsldoc.load("d:\\inetpub\\wwwroot\\sampleXSLWithObject.xml");
xsltemp.stylesheet = xsldoc.documentElement;
xslproc = xsltemp.createProcessor();
xmldoc.loadXML("<level>Twelve</level>");
xslproc.input = xmldoc;

xslproc.addObject(xmldoc, "urn:my-object");
xslproc.transform();
alert(xslproc.output);

File Name: d:\inetpub\wwwroot\sampleXSLWithObject.xml

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
 xmlns:myObj="urn:my-object">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
   <xsl:element name="stage">
   <xsl:value-of select="myObj:get-text()"/>
   </xsl:element>
</xsl:template>
</xsl:stylesheet>

Output

<?xml version="1.0" encoding="UTF-16"?>
<stage>
Twelve
</stage>
[Visual Basic]

Visual Basic Syntax

objXSLProcessor.addObject(obj, namespaceURI)

Parameters

obj
The object to pass in.
namespaceURI
The namespace to use inside the style sheet to identify the object.

Example

The following Visual Basic example passes an object to the style sheet.

Dim xsldoc As New Msxml2.FreeThreadedDOMDocument
Dim xmldoc As New Msxml2.FreeThreadedDOMDocument
Dim xsltemp As New Msxml2.XSLTemplate
Dim xslproc As Msxml2.IXSLProcessor

xsldoc.Load "d:\inetpub\wwwroot\sampleXSLWithObject.xml"
Set xsltemp.stylesheet = xsldoc.documentElement
Set xslproc = xsltemp.createProcessor
xmldoc.loadXML "<level>Twelve</level>"
xslproc.input = xmldoc

xslproc.addObject xmldoc, "urn:my-object"
xslproc.Transform
MsgBox xslproc.output

File Name: d:\inetpub\wwwroot\sampleXSLWithObject.xml

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:myObj="urn:my-object">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
   <xsl:element name="stage">
   <xsl:value-of select="myObj:get-text()"/>
   </xsl:element>
</xsl:template>
</xsl:stylesheet>

Output

<?xml version="1.0" encoding="UTF-16"?>
<stage>
Twelve
</stage>
[C/C++]

C/C++ Syntax

HRESULT addObject (IDispatch* obj, BSTR namespaceURI);

Parameters

obj [in]
The object to pass in.
namespaceURI [in]
The namespace that will be used inside the style sheet to identify the object.

C/C++ Return Values

E_FAIL if readyState is READYSTATE_INTERACTIVE.

Remarks

Numbers are coerced to double, everything is coerced into a string, and objects return an error.

The syntax get- is used to retrieve the property value exposed by the object that was passed into the style sheet. In the preceding example, the value for the property 'text' was retrieved as follows:

<xsl:value-of select="myObj:get-text()"/>

For example, if the object that was passed into the style sheet included a property called 'sheepcount', to retrieve the value of that property, you would use the syntax:

<xsl:value-of select="myObj:get-countsheep()"/>

See Also

Applies to: IXSLProcessor


addParameter Method

Adds parameters into an XSL Transformations (XSLT) style sheet.

[Script]

Script Syntax

objXSLProcessor.addParameter(baseName, parameter, namespaceURI);

Parameters

baseName
The name that will be used inside the style sheet to identify the parameter context.
parameter
A number, Boolean, string, IXMLDOMNodeList, or IXMLDOMNode. Passing in a single node will produce a node list that contains one node (shortcut).
namespaceURI (optional)
An optional namespace.

Example

var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xslProc;
xslDoc.async = false;
xslDoc.load("sample.xsl");
xslt.stylesheet = xslDoc;
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
xslProc = xslt.createProcessor();
xslProc.input = xmlDoc;
xslProc.addParameter("param1", "Hello");
xslProc.transform();
alert(xslProc.output);

File Name: Sample.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      The parameter value was: <xsl:value-of select="$param1"/>
  </xsl:template>
</xsl:stylesheet>
[Visual Basic]

Visual Basic Syntax

objXSLProcessor.addParameter(baseName, parameter, namespaceURI)

Parameters

baseName
The name that will be used inside the style sheet to identify the parameter context.
parameter
A number, Boolean, string, IXMLDOMNodeList, or IXMLDOMNode. Passing in a single node will produce a node list that contains one node (shortcut).
namespaceURI (optional)
An optional namespace.

Example

Dim xslt As New Msxml2.XSLTemplate
Dim xslDoc As New Msxml2.FreeThreadedDOMDocument
Dim xmlDoc As New Msxml2.DOMDocument
Dim xslProc As IXSLProcessor
xslDoc.async = False
xslDoc.Load "sample.xsl"
Set xslt.stylesheet = xslDoc
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set xslProc = xslt.createProcessor()
xslProc.input = xmlDoc
xslProc.addParameter "param1", "Hello"
xslProc.Transform
MsgBox xslProc.output

File Name: Sample.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      The parameter value was: <xsl:value-of select="$param1"/>
  </xsl:template>
</xsl:stylesheet>
[C/C++]

C/C++ Syntax

HRESULT addParameter (BSTR baseName, VARIANT parameter, BSTR
namespaceURI);

Parameters

baseName [in]
The name that will be used inside the style sheet to identify the parameter context.
parameter [in]
A number, Boolean, string, node list, or node. Passing in a single node will produce a node list that contains one node (shortcut).
namespaceURI [in, optional]
An optional namespace.

C/C++ Return Values

E_FAIL if readyState is READYSTATE_INTERACTIVE.

Example

#import "msxml3.dll"
using namespace MSXML2;

#define CHECK_AND_RELEASE(pInterface)  \
if(pInterface) \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

#define RELEASE(pInterface)  \
   {\
pInterface->Release();\
pInterface = NULL;\
   }\

BOOL XSLProcessorAddParameterDemo ()
{
   BOOL bResult = FALSE;
   short sResult = FALSE;
   HRESULT hr;
   IXMLDOMDocument2 *pStyleSheet=NULL;
   IXSLTemplate *pIXSLTemplate=NULL;
   IXSLProcessor *pIXSLProcessor=NULL;
   VARIANT varValue;

   try
   {
      hr = CoCreateInstance(CLSID_XSLTemplate, NULL, CLSCTX_SERVER,
         IID_IXSLTemplate, (LPVOID*)(&pIXSLTemplate));
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXSLTemplate)
      {
         hr=CoCreateInstance(CLSID_FreeThreadedDOMDocument, NULL,
CLSCTX_SERVER, IID_IXMLDOMDocument2, (LPVOID*)(&pStyleSheet));
         SUCCEEDED(hr) ? 0 : throw hr;

         if(pStyleSheet)
         {
            hr=pStyleSheet->put_async(VARIANT_FALSE);
            if(SUCCEEDED(hr))
            {
               hr=pStyleSheet->load(_variant_t
                  (_T("d:\\inetpub\\wwwroot\\samplexsl.xml")), &sResult);
               if(SUCCEEDED(hr) && (sResult==VARIANT_TRUE))
               {
                  hr=pIXSLTemplate->putref_stylesheet(pStyleSheet);
                  if(SUCCEEDED(hr))
                  {
                     hr=pIXSLTemplate->createProcessor(&pIXSLProcessor);
                     SUCCEEDED(hr) ? 0 : throw hr;
                     if(pIXSLProcessor)
                     {
                        hr=CoCreateInstance(CLSID_DOMDocument, NULL,
                           CLSCTX_SERVER, IID_IXMLDOMDocument2,
                           (LPVOID*)(&pIXMLDOMDocument));
                        SUCCEEDED(hr) ? 0 : throw hr;

                        if(pIXMLDOMDocument)
                        {
                           hr=pIXMLDOMDocument->put_async(VARIANT_FALSE);
                           if(SUCCEEDED(hr))
                           {
                              hr=pIXMLDOMDocument->load(_variant_t
( _T("d:\\inetpub\\wwwroot\\sampleXSLWithParam.xml")), &sResult);
                              if(SUCCEEDED(hr) && (sResult==VARIANT_TRUE))
                              {
                                 hr=pIXSLProcessor->put_input(_variant_t
                                     (pIXMLDOMDocument));
                                 if(SUCCEEDED(hr))
                                 {
                                    hr=pIXSLProcessor->addParameter
( _T("fooText"), _variant_t(_T("Add Parameter Test")), _T(""));
                                    if(SUCCEEDED(hr))
                                       bResult=TRUE;
                                       hr=pIXSLProcessor->transform(
                                          &sResult);
                                    if(SUCCEEDED(hr)&& (sResult ==
                                       VARIANT_TRUE))
                                    {
                                       pIXSLProcessor->get_output(
                                          &varValue);
                                       ::MessageBox(NULL,
                                       _bstr_t(varValue),
                                       _T("Transformed Output"), MB_OK);
                                    }
                                 }
                              }
                           }
                           RELEASE(pIXMLDOMDocument);
                        }
                     }
                  }
               }
            }
            RELEASE(pStyleSheet);
         }
         RELEASE(pIXSLTemplate);
      }
   }
   catch(...)
   {
      CHECK_AND_RELEASE(pIXSLTemplate);
      CHECK_AND_RELEASE(pStyleSheet);
      CHECK_AND_RELEASE(pIXMLDOMDocument);
      DisplayErrorToUser();
   }
   return bResult;
}

Style Sheet: "d:\\inetpub\\wwwroot\\sampleXSLWithParam.xml"

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:myObj="urn:my-object">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="fooText"/>

<xsl:template match="/">
<xsl:element name="bar">
<xsl:value-of select="$fooText"/>
</xsl:element>
</xsl:template>

</xsl:stylesheet>

Output (in a message box)

<?xml version="1.0" encoding="UTF-16"?>
<bar>
Add Parameter Test
</bar>

Remarks

The addParameter method can be called on transformNode handlers and between transform calls (in asynchronous processing), and further processing will use the updated parameter. Added parameters are referenced by <xsl:param> within the style sheet.

See Also

Applies to: IXSLProcessor


ancestorChildNumber Method

Returns the number of the nearest ancestor of a node with the requested node name.

[Script]

Script Syntax

lValue = oXTLRuntime.ancestorChildNumber(bstrNodeName, pNode);

Parameters

bstrNodeName
A string. The node name of the desired ancestor.
pNode
An object. The node from which to start the search.

Return Value

Long integer. Returns the number of the ancestor relative to its sibling nodes. The first entry in the list is assigned the value "1". Returns Null if there is no such ancestor.

[Visual Basic]

Visual Basic Syntax

lValue = oXTLRuntime.ancestorChildNumber(bstrNodeName, pNode)

Parameters

bstrNodeName
A string. The node name of the desired ancestor.
pNode
An object. The node from which to start the search.

Return Value

Long integer. Returns the number of the ancestor relative to its sibling nodes. The first entry in the list is assigned the value "1". Returns Null if there is no such ancestor.

[C/C++]

C/C++ Syntax

HRESULT ancestorChildNumber(
    BSTR bstrNodeName,
    IXMLDOMNode* pNode,
    long* pNumber);

Parameters

bstrNodeName [in]
The node name of the desired ancestor.
pNode [in]
The node from which to start the search.
pNumber [out, retval]
The number of the ancestor relative to its sibling nodes. The first entry in the list is assigned the value "1". Returns Null if there is no such ancestor.

C/C++ Return Values

Returns S_OK if successful, or an error code otherwise.

See Also

Applies to: IXTLRuntime


appendChild Method

Appends a new child node as the last child of the node.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNode.appendChild(newChild);

Parameters

newChild
An object. Address of the new child node to be appended at the end of the list of children belonging to this node.

Return Value

An object. Returns the new child node successfully appended to the list.

Example

The following script example creates a new IXMLDOMNode object, and then uses the appendChild method to append it to the document's list of children.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var newNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
alert(root.xml);
newNode = xmlDoc.createNode(1, "VIDEOS", "");
root.appendChild(newNode);
alert(root.xml);

Remarks

This is equivalent to calling insertBefore(newChild, null). For more information, see insertBefore Method.

[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNode.appendChild(newChild)

Parameters

newChild
An object. The address of the new child node to be appended at the end of the list of children belonging to this node.

Return Value

An object. Returns the new child node successfully appended to the list.

Example

The following Microsoft® Visual Basic® example creates a new IXMLDOMNode object, and then uses the appendChild method to append it to the document's list of children.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim newNode As IXMLDOMNode

xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
MsgBox root.xml
Set newNode = xmlDoc.createNode(NODE_ELEMENT, "VIDEOS", "")
root.appendChild newNode
MsgBox root.xml

Remarks

This is equivalent to calling insertBefore(newChild, null). For more information, see insertBefore Method.

[C/C++]

C/C++ Syntax

HRESULT appendChild(
    IXMLDOMNode *newChild,
    IXMLDOMNode **outNewChild);

Parameters

newChild [in]
The address of the new child node to be appended to the end of the list of children of this node.
outNewChild [out, retval]
The new child node successfully appended to the list. If Null, no object is created.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if newChild is Null.
E_FAIL
The value returned if an error occurs.

Remarks

If newChild has an existing parent, the node is automatically removed from that parent before being inserted into its new location.

A node retains its namespace information even when moved. Moving a node does not create a namespace declaration; declarations are added when retrieving the XML source (through the save or xml) to ensure that all namespaces are properly declared.

When inserting a node tree under another node that has a different owner document, the ownerDocument property for each inserted node is changed to match the owner document of its new parent.

When moving a node tree to another document, the content of all entity reference nodes contained therein is updated to conform to the new document. If the new document does not declare an entity that was moved into it, the entity reference will have no children, and the old content is removed. Existing references to nodes under the entity reference are still valid, but the node whose parent previously was the entity reference now has a null parent.

See Also

save Method | xml Property | ownerDocument Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


appendData Method

Appends the supplied string to the existing string data.

[Script]

Script Syntax

oXMLDOMCharacterData.appendData(data);

Parameters

data
A string containing the data that is to be appended to the existing string.

Example

The following script example creates an IXMLDOMComment object and uses the appendData method to add text to the string.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var comment;
xmlDoc.async = false;
xmlDoc.load("books.xml");
comment = xmlDoc.createComment("Hello World!");
comment.appendData("Ellohay Orldway!");
alert(comment.data);
[Visual Basic]

Visual Basic Syntax

oXMLDOMCharacterData.appendData(data)

Parameters

data
A string containing the data that is to be appended to the existing string.

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMComment object and uses the appendData method to add text to the string.

Dim xmlDoc As New Msxml2.DOMDocument
Dim comment As IXMLDOMComment
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set comment = xmlDoc.createComment("Hello World!")
comment.appendData ("Ellohay Orldway!")
MsgBox (comment.Data)
[C/C++]

C/C++ Syntax

HRESULT appendData(
    BSTR data);

Parameters

data [in]
The string data to be appended to the existing string.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned if the string is not appended.
E_FAIL
The value returned if an error occurs.

Remarks

The length property is also updated by this operation.

See Also

length Property (IXMLDOMCharacterData)

Applies to: IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | IXMLDOMText


childNumber Method

Returns the number of the node relative to siblings of the same node name.

[Script]

Script Syntax

lValue = oXTLRuntime.childNumber(pNode);

Parameters

pNode
An object. The node for which the child number is to be returned.

Return Value

Long integer. Returns the index for the node in its parent's list of child nodes with that name. The first entry in the list is assigned the value "1".

[Visual Basic]

Visual Basic Syntax

lValue = oXTLRuntime.childNumber(pNode)

Parameters

pNode
An object. The node for which the child number is to be returned.

Return Value

Long integer. Returns the index for the node in its parent's list of child nodes with that name. The first entry in the list is assigned the value "1".

[C/C++]

C/C++ Syntax

HRESULT childNumber(IXMLDOMNode* pNode, long* pNumber);

Parameters

pNode [in]
The node for which the child number is to be returned.
pNumber [out, retval]
The index for the node in its parent's list of child nodes with that name. The first entry in the list is assigned the value "1".

C/C++ Return Values

S_OK
The value returned if successful.

See Also

Applies to: IXTLRuntime


clone Method

Clones a copy of the current IXMLDOMSelection, with the same position and context.

[Script]

Script Syntax

var NewObjXMLDOMSelection = objXMLDOMSelection.clone();

Example

//Create a DOMDocument2 object and load some XML:
xmldoc = new ActiveXObject("Msxml2.DOMDocument");
xmldoc.loadXML("<root><elem1>foo</elem1><elem2>bar</elem2></root>");
//Create an XMLDOMSelection object from selected nodes:
xpath = xmldoc.selectNodes("root/elem1");
//Cache the XPath expression and context:
xpath.expr = "root/elem1";
xpath.context = xmldoc;

//Clone the XMLDOMSelection object
xpath2 = xpath.clone();
temp1 = xpath.peekNode();  // temp1 == <elem1/>
temp2 = xpath2.peekNode();  // temp2 == <elem1/> Note the position and
// context are maintained.
[Visual Basic]

Visual Basic Syntax

Set NewObjXMLDOMSelection = objXMLDOMSelection.clone

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim xpath As IXMLDOMSelection
Dim xpath2 As IXMLDOMSelection
Dim temp1 As IXMLDOMNode
Dim temp2 As IXMLDOMNode
xmlDoc.loadXML ("<root><elem1>foo</elem1><elem2>bar</elem2></root>")
' Create an XMLDOMSelection object from selected nodes:
Set xpath = xmlDoc.selectNodes("root/elem1")
' Cache the XPath expression and context:
xpath.expr = "root/elem1"
Set xpath.context = xmlDoc
' Clone the XMLDOMSelection object
Set xpath2 = xpath.Clone()
Set temp1 = xpath.peekNode()    ' temp1 == <elem1/>
Set temp2 = xpath2.peekNode()   ' temp2 == <elem1/> Note the position and
' context are maintained.
[C/C++]

C/C++ Syntax

HRESULT clone(IXMLDOMSelection ** ppNode);

Parameters

ppNode [out, retval]
The returned copy of the IXMLDOMSelection object.

C/C++ Return Values

S_OK
The value returned if the cloning is successful.
E_INVALIDARG
The value returned if the input argument is Null.

See Also

Applies to: IXMLDOMSelection


cloneNode Method

Clones a new node.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNode.cloneNode(deep);

Parameters

deep
Boolean. A flag that indicates whether to recursively clone all nodes that are descendants of this node. If True, creates a clone of the complete tree below this node. If False, clones this node and its attributes only.

Return Value

Object. Returns the newly created clone node.

Example

The following script example clones a node, and then appends it as a child of the top-level node.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var currNode;
var MyNewNode;
xmlDoc.async = false;
xmlDoc.load("books.xml")
root = xmlDoc.documentElement;
currNode = root.childNodes.item(1);
MyNewNode = currNode.cloneNode(true);
root.appendChild(MyNewNode);
alert(xmlDoc.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNode.cloneNode(deep)

Parameters

deep
Boolean. A flag that indicates whether to recursively clone all nodes that are descendants of this node. If True, creates a clone of the complete tree below this node. If False, clones this node and its attributes only.

Return Value

An object. Returns the newly created clone node.

Example

The following Microsoft® Visual Basic® example clones a node, and then appends it as a child of the top-level node.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim currNode As IXMLDOMNode
Dim MyNewNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
Set currNode = root.childNodes.Item(1)
Set MyNewNode = currNode.cloneNode(True)
root.appendChild MyNewNode
MsgBox xmlDoc.xml
[C/C++]

C/C++ Syntax

HRESULT cloneNode(
    VARIANT_BOOL deep,
    IXMLDOMNode **cloneRoot);

Parameters

deep [in]
A flag that indicates whether to recursively clone all nodes that are descendants of this node. If True, creates a clone of the complete tree below this node. If False, clones this node and its attributes only.
cloneRoot [out, retval]
A newly created clone node.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if cloneRoot is Null.

Remarks

The cloned node has the same property values as this node for the following properties: nodeName property, nodeValue property, nodeType property, parentNode property, ownerDocument property, and, if it is an element, attributes property. The value of the clone's childNodes property depends on the setting of the deep flag parameter.

Note If the node is the DOMDocument node, it is safer to clone the document using the save method, as follows.
doc.save(doc2);

See Also

nodeName Property | nodeValue Property | nodeType Property | parentNode Property | ownerDocument Property | attributes Property | childNodes Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


createAttribute Method

Creates a new attribute with the specified name.

[Script]

Script Syntax

var objXMLDOMAttribute = oXMLDOMDocument.createAttribute(name);

Parameters

name
A string specifying the name of the new attribute object. This name is subsequently available as the new node's nodeName property.

Return Value

An object. Returns the new IXMLDOMAttribute object.

Example

The following script example creates a new attribute called ID and adds it to the attributes of the DOMDocument object.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var newAtt;
var namedNodeMap;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
newAtt = xmlDoc.createAttribute("ID");
namedNodeMap = root.attributes;
namedNodeMap.setNamedItem(newAtt);
for (var i=0; i<namedNodeMap.length; i++) {
  alert(namedNodeMap.item(i).xml);
}
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMAttribute = oXMLDOMDocument.createAttribute(name)

Parameters

name
A string specifying the name of the new attribute object. This name is subsequently available as the new node's nodeName property.

Return Value

An object. Returns the new IXMLDOMAttribute object.

Example

The following Visual Basic example creates a new attribute called ID and adds it to the attributes of the DOMDocument object.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim newAtt As IXMLDOMAttribute
Dim namedNodeMap As IXMLDOMNamedNodeMap
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
Set newAtt = xmlDoc.createAttribute("ID")
Set namedNodeMap = root.Attributes
namedNodeMap.setNamedItem newAtt
For i = 0 To (namedNodeMap.length - 1)
  MsgBox (namedNodeMap.Item(i).xml)
Next
[C/C++]

C/C++ Syntax

HRESULT createAttribute(
    BSTR name,
    IXMLDOMAttribute **attribute);

Parameters

name [in]
The name of the new attribute object. This name is subsequently available as the new node's nodeName property.
attribute [out, retval]
The address of the new IXMLDOMAttribute object.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if attribute is Null.
E_FAIL
The value returned if an error occurs.

Remarks

Creating an attribute with this method is the same as using createNode where the type parameter value is NODE_ATTRIBUTE and no namespace is specified.

You cannot create a namespace-qualified attribute using the createAttribute method. Regardless of whether a namespace prefix is included in name, the namespaceURI property for the new attribute is set to an empty string, "". An attribute constructed as part of an XML document load operation will never have both a prefix and an empty namespace Uniform Resource Identifier (URI). You can only create a namespace-qualified attribute using the createNode method of the DOMDocument.

No data value is set for the attribute during the create operation. You can set the value by calling the setAttribute method of the element object.

Although this method creates the new object in the context of this document, it does not automatically add the new object to the document tree. In other words, although the ownerDocument property of the new node points to this document object, the parentNode property remains a Null. To associate the attribute with an element, call the setAttribute method of the IXMLDOMElement object.

Because the parentNode property of an attribute always returns a Null value, this property will not change after associating the new attribute with an element using the setAttribute method.

The nodeType property has the value NODE_ATTRIBUTE.

See Also

createNode Method | namespaceURI Property (IXMLDOMNode) | setAttribute Method | ownerDocument Property | parentNode Property | nodeType Property | nodeName Property | IXMLDOMElement | IXMLDOMAttribute

Applies to: DOMDocument


createCDATASection Method

Creates a CDATA section node that contains the supplied data.

[Script]

Script Syntax

var objXMLDOMCDATASection = oXMLDOMDocument.createCDATASection(data);

Parameters

data
A string specifying the value to be supplied to the new IXMLDOMCDATASection object's nodeValue property.

Return Value

An object. Returns the new IXMLDOMCDATASection object.

Example

The following script example creates a new CDATA section node and appends it as the last child node of the DOMDocument object.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var CDATASection;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
CDATASection = xmlDoc.createCDATASection("Hello World!");
root.appendChild(CDATASection);
alert(root.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMCDATASection = oXMLDOMDocument.createCDATASection(data)

Parameters

data
A string specifying the value to be supplied to the new CDATASection object's nodeValue property.

Return Value

An object. Returns the new IXMLDOMCDATASection object.

Example

The following Visual Basic example creates a new CDATA section node and appends it as the last child node of the DOMDocument object.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim CDATASection As IXMLDOMCDATASection
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
Set CDATASection = xmlDoc.createCDATASection("Hello World!")
root.appendChild CDATASection
MsgBox (root.xml)
[C/C++]

C/C++ Syntax

HRESULT createCDATASection(
    BSTR data,
    IXMLDOMCDATASection **cdata);

Parameters

data [in]
The value to be supplied to the new CDATA section object's nodeValue property.
cdata [out, retval]
The address of the new IXMLDOMCDATASection.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if cdata is Null.
E_FAIL
The value returned if an error occurs.

Remarks

Creating a CDATA section with this method is the same as using createNode where the type parameter value is NODE_CDATA_SECTION and no namespace is specified. You cannot specify a namespace with the createCDATASection method.

Although this method creates the new object in the context of this document, it does not automatically add the new object to the document tree. In other words, although the ownerDocument property of the new node points to this document object, the parentNode property is set to Null. To add the new object, you must explicitly call one of the node insert methods, insertBefore method, replaceChild method, or appendChild method.

The new object's nodeType property has the value NODE_CDATA_SECTION.

See Also

createNode Method | ownerDocument Property | parentNode Property | insertBefore Method | nodeType Property | nodeValue Property | replaceChild Method | appendChild Method | IXMLDOMCDATASection

Applies to: DOMDocument


createComment Method

Creates a comment node that contains the supplied data.

[Script]

Script Syntax

var objXMLDOMComment = oXMLDOMDocument.createComment(data);

Parameters

data
The string specifying the value to be supplied to the new Comment object's nodeValue property.

Return Value

An object. Returns the new IXMLDOMComment.

Example

The following script example creates a new comment node and appends it as the last child node of the DOMDocument object.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var comment;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
comment = xmlDoc.createComment("Hello World!");
root.appendChild(comment);
alert(root.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMComment = oXMLDOMDocument.createComment(data)

Parameters

data
A string specifying the value to be supplied to the new Comment object's nodeValue property.

Return Value

An object. Returns the new IXMLDOMComment.

Example

The following Visual Basic example creates a new comment node and appends it as the last child node of the DOMDocument object.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim comment As IXMLDOMComment
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
Set comment = xmlDoc.createComment("Hello World!")
root.appendChild comment
MsgBox (root.xml)
[C/C++]

C/C++ Syntax

HRESULT createComment(
    BSTR data,
    IXMLDOMComment **comment);

Parameters

data [in]
A value to be supplied to the new comment object's nodeValue property.
comment [out, retval]
The address of the new IXMLDOMComment object.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if comment is Null.
E_FAIL
The value returned if an error occurs.

Remarks

Creating a comment with this method is the same as using createNode where the type parameter value is NODE_COMMENT and no namespace is specified. You cannot specify a namespace with the createComment method.

Although this method creates the new object in the context of this document, it does not automatically add the new object to the document tree. In other words, although the ownerDocument property of the new node points to this document object, the parentNode property is set to Null. To add the new object, you must explicitly call one of the node insert methods, insertBefore method, replaceChild method, or appendChild method.

The new object's nodeType property has the value NODE_COMMENT.

See Also

createNode Method | ownerDocument Property | parentNode Property | insertBefore Method | replaceChild Method | appendChild Method | nodeType Property | nodeValue Property | IXMLDOMComment

Applies to: DOMDocument


createDocumentFragment Method

Creates an empty IXMLDOMDocumentFragment object.

[Script]

Script Syntax

var objXMLDOMDocumentFragment = oXMLDOMDocument.createDocumentFragment();

Return Value

An object. Returns the empty IXMLDOMDocumentFragment object.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var docFragment;
xmlDoc.async = false;
xmlDoc.loadXML("<root/>");
docFragment = xmlDoc.createDocumentFragment();
docFragment.appendChild(xmlDoc.createElement("node1"));
docFragment.appendChild(xmlDoc.createElement("node2"));
docFragment.appendChild(xmlDoc.createElement("node3"));
alert(docFragment.xml);
xmlDoc.documentElement.appendChild(docFragment);
alert(xmlDoc.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMDocumentFragment = oXMLDOMDocument.createDocumentFragment

Return Value

An object. Returns the empty IXMLDOMDocumentFragment object.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim docFragment As IXMLDOMDocumentFragment
xmlDoc.async = False
xmlDoc.loadXML "<root/>"
Set docFragment = xmlDoc.createDocumentFragment()
docFragment.appendChild xmlDoc.createElement("node1")
docFragment.appendChild xmlDoc.createElement("node2")
docFragment.appendChild xmlDoc.createElement("node3")
MsgBox docFragment.xml
xmlDoc.documentElement.appendChild docFragment
MsgBox xmlDoc.xml
[C/C++]

C/C++ Syntax

HRESULT createDocumentFragment(
    IXMLDOMDocumentFragment **docFrag);

Parameters

docFrag [out, retval]
The address of the empty IXMLDOMDocumentFragment.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if docFrag is Null.
E_FAIL
The value returned if an error occurs.

Remarks

Creating a document fragment with this method is the same as using createNode where the type parameter value is NODE_DOCUMENT_FRAGMENT and no namespace is specified. You cannot specify a namespace with the createDocumentFragment method.

Although this method creates the new object in the context of this document, it does not automatically add the new object to the document tree. In other words, although the ownerDocument property of the new node points to this document object, the parentNode property is set to Null. To add the new object, you must explicitly call one of the node insert methods, insertBefore method, replaceChild method, or appendChild method.

The nodeType property has the value NODE_DOCUMENT_FRAGMENT.

See Also

createNode Method | ownerDocument Property | parentNode Property | nodeType property | insertBefore Method | replaceChild Method | appendChild Method | IXMLDOMDocumentFragment

Applies to: DOMDocument


createElement Method

Creates an element node using the specified name.

[Script]

Script Syntax

var objXMLDOMElement = oXMLDOMDocument.createElement(tagName);

Parameters

tagName
A string specifying the name for the new element node. The name is case-sensitive. This name is subsequently available as the element node's nodeName property.

Return Value

An object. Returns the IXMLDOMElement object for the new element.

Example

The following script example creates an element called PAGES and appends it to an IXMLDOMNode object. It then sets the text value of the element to 400.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var newElem;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
newElem = xmlDoc.createElement("PAGES");
root.childNodes.item(1).appendChild(newElem);
root.childNodes.item(1).lastChild.text = "400";
alert(root.childNodes.item(1).xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMElement = oXMLDOMDocument.createElement(tagName)

Parameters

tagName
A string specifying the name for the new element node. The name is case-sensitive. This name is subsequently available as the element node's nodeName property.

Return Value

An object. Returns the IXMLDOMElement object for the new element.

Example

The following Microsoft® Visual Basic® example creates an element called PAGES and appends it to an IXMLDOMNode object. It then sets the text value of the element to 400.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim newElem As IXMLDOMElement
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
Set newElem = xmlDoc.createElement("PAGES")
root.childNodes.Item(1).appendChild newElem
root.childNodes.Item(1).lastChild.Text = "400"
MsgBox root.childNodes.Item(1).xml
[C/C++]

C/C++ Syntax

HRESULT createElement(
    BSTR tagName,
    IXMLDOMElement **element);

Parameters

tagName [in]
The name for the new element node. It is case-sensitive. This name is subsequently available as the element node's nodeName property.
element [out,retval]
The address of the IXMLDOMElement interface for the new element.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if element is Null.
E_FAIL
The value returned if an error occurs.

Remarks

Creating an element with this method is the same as using createNode where the type parameter value is NODE_ELEMENT and no namespace is specified.

You cannot create a namespace-qualified element using the createElement method. Regardless of whether a namespace prefix is included in tagName, the namespaceURI property for the new element node is set to an empty string, "". An element node constructed as part of an XML document load operation will never have both a prefix and an empty namespace Uniform Resource Identifier (URI). You can only create a namespace-qualified element using the createNode method of the DOMDocument object.

Although this method creates the new object in the context of this document, it does not automatically add the new object to the document tree. In other words, although the ownerDocument property of the new node points to this document object, the parentNode property is set to Null. To add the new object, you must explicitly call one of the node insert methods, insertBefore method, replaceChild method, or appendChild method.

The nodeType property has the value NODE_ELEMENT.

See Also

createNode Method | namespaceURI Property (IXMLDOMNode) | ownerDocument Property | parentNode Property | nodeName Property | nodeType Property | insertBefore Method | replaceChild Method | appendChild Method | IXMLDOMElement

Applies to: DOMDocument


createEntityReference Method

Creates a new EntityReference object.

[Script]

Script Syntax

var objXMLDOMEntityReference = oXMLDOMDocument.createEntityReference(name);

Parameters

name
A string specifying the name of the entity referenced. This name is subsequently available as the new object's nodeName property.

Return Value

An object. Returns the new IXMLDOMEntityReference object.

Example

The following script example creates a new IXMLDOMEntityReference object and appends it to an IXMLDOMNode object.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var MyEntity;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
MyEntity = xmlDoc.createEntityReference("newRef");
root.childNodes.item(0).appendChild(MyEntity);
alert(root.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMEntityReference = oXMLDOMDocument.createEntityReference(name)

Parameters

name
A string specifying the name of the entity referenced. This name is subsequently available as the new object's nodeName property.

Return Value

An Object. Returns the new IXMLDOMEntityReference object.

Example

The following Visual Basic example creates a new IXMLDOMEntityReference object and appends it to an IXMLDOMNode object.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim MyEntity As IXMLDOMEntityReference
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
Set MyEntity = xmlDoc.createEntityReference("newRef")
root.childNodes.Item(0).appendChild MyEntity
MsgBox root.xml
[C/C++]

C/C++ Syntax

HRESULT createEntityReference(
    BSTR name,
    IXMLDOMEntityReference **entityRef);

Parameters

name [in]
The name of the entity referenced. This name is subsequently available as the new object's nodeName property.
entityRef [out, retval]
The address of the new IXMLDOMEntityReference object.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if entityRef is Null.
E_FAIL
The value returned if an error occurs.

Remarks

Creating an entity reference with this method is the same as using createNode where the type parameter value is NODE_ENTITY_REFERENCE and no namespace is specified. You cannot specify a namespace within the name parameter.

Although this method creates the new object in the context of this document, it does not automatically add the new object to the document tree. In other words, although the ownerDocument property of the new node points to this document object, the parentNode property is set to Null. To add the new object, you must explicitly call one of the node insert methods, insertBefore method, replaceChild method, or appendChild method.

The nodeType property has the value NODE_ENTITY_REFERENCE.

See Also

nodeName Property | nodeType Property | createNode Method | ownerDocument Property | parentNode Property | insertBefore Method | replaceChild Method | appendChild Method | IXMLDOMEntityReference

Applies to: DOMDocument


createNode Method

Creates a node using the supplied type, name, and namespace.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMDocument.createNode(Type, name, namespaceURI);

Parameters

Type
A variant. A value that uniquely identifies the node type. This can be specified using either the integer value or the string value. For the complete list of values, see XML DOM Enumerated Constants or the description for the name parameter.
name
A string containing the value for the new node's nodeName property. The relationship between the node name and node Type is summarized below.
namespaceURI
A string defining the namespace URI. If specified, the node is created in the context of the namespaceURI with the prefix specified on the node name. If the name parameter does not have a prefix, this is treated as the default namespace.

Return Value

Object. Returns the newly created node.

Example

The following script example creates an attribute node called "Sci-Fi" and adds it to the attributes for the DOMDocument object.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var MyNode;
var namedNodeMap;
xmlDoc.async = false;
xmlDoc.load("books.xml");
MyNode = xmlDoc.createNode(2, "Sci-Fi", "");
namedNodeMap = xmlDoc.documentElement.childNodes.item(0).attributes;
namedNodeMap.setNamedItem(MyNode);
alert(xmlDoc.documentElement.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMDocument.createNode(Type, name, namespaceURI)

Parameters

Type
A variant. A value that uniquely identifies the node type. This can be specified using either the integer value or the string value. For the complete list of values, see the XML DOM Enumerated Constants or the description for the name parameter.
name
A string containing the value for the new node's nodeName property. The relationship between the node name and node Type is summarized below.
namespaceURI
A string defining the namespace URI. If specified, the node is created in the context of the namespaceURI with the prefix specified on the node name. If the name parameter does not have a prefix, this is treated as the default namespace.

Return Value

An object. Returns the newly created node.

Example

The following Microsoft® Visual Basic® example creates an attribute node called "Sci-Fi" and adds it to the attributes for the DOMDocument object.

Dim xmlDoc As New Msxml2.DOMDocument
Dim MyNode As IXMLDOMNode
Dim namedNodeMap As IXMLDOMNamedNodeMap
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set MyNode = xmlDoc.createNode(NODE_ATTRIBUTE, "Sci-Fi", "")
Set namedNodeMap = xmlDoc.documentElement.childNodes.Item(0).Attributes
namedNodeMap.setNamedItem MyNode
MsgBox (xmlDoc.documentElement.xml)
[C/C++]

C/C++ Syntax

HRESULT createNode(
    VARIANT Type,
    BSTR name,
    BSTR namespaceURI,
    IXMLDOMNode **node);

Parameters

Type [in]
The value that uniquely identifies the node type. This can be specified using either the integer value or the string value. For the complete list of values, see the XML DOM Enumerated Constants or the description given for the name parameter.
name [in]
The value for the new node's nodeName property. The relationship between the node name and node Type is summarized in the table below.
namespaceURI [in]
The namespace URI. If specified, the node is created in the context of the namespaceURI parameter with the prefix specified on the node name. If the name parameter does not have a prefix, this is treated as the default namespace.
node [out, retval]
The newly created node.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if node is Null.
E_FAIL
The value returned if an error occurs.

Remarks

The name parameter depends on the value of the type parameter:

NODE_ATTRIBUTE | The name of the attribute.
NODE_CDATA_SECTION, NODE_COMMENT, NODE_DOCUMENT, NODE_DOCUMENT_FRAGMENT, NODE_TEXT | The nodeName property for these node types is a constant value; the name parameter is ignored.
NODE_DOCUMENT_TYPE | The name of the document type; for example, the xxx in <!DOCTYPE xxx ...>.
NODE_ELEMENT | The name of the XML tag, with any namespace prefix included if present.
NODE_ENTITY | The name of the entity.
NODE_ENTITY_REFERENCE | The name of the entity referenced. The name does not include the leading ampersand or the trailing semicolon. The name includes the namespace, if one is present.
NODE_NOTATION | The name of the notation.
NODE_PROCESSING_INSTRUCTION | The target, the first token following the <? characters.

You cannot create a node of type NODE_DOCUMENT, NODE_DOCUMENT_TYPE, NODE_ENTITY, or NODE_NOTATION.

When a node is created, it is created in the context of a namespace if one is supplied (if the namespaceURI parameter is supplied). If one is not supplied, the node is created in the namespace of the document. If namespaceURI is specified, the node is created in the context of the namespaceURI with the prefix specified on the node name.

For node types that do not have names, the empty string, "", should be passed as the name parameter.

For elements and entity references, when the namespaceURI parameter is anything other than "" and the name parameter does not contain a prefix (xxx in xxx:yyy), the namespaceURI is treated as the default namespace.

Attributes cannot be scoped to a default namespace, and other elements are not qualified to a particular namespace; they are treated as being from the namespace defined by the document itself.

When namespaceURI is the empty string, "", the node is created within the special namespace of the current document. Creating a qualified node without specifying a nonempty namespaceURI returns an error. This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

nodeName Property

Applies to: DOMDocument


createProcessingInstruction Method

Creates a processing instruction node that contains the supplied target and data.

[Script]

Script Syntax

var objXMLDOMProcessingInstruction =
oXMLDOMDocument.createProcessingInstruction(target, data);

Parameters

target
A string specifying the target part of the processing instruction. This supplies the nodeName property of the new object.
data
A string specifying the rest of the processing instruction preceding the closing ?> characters. This supplies the nodeValue property for the new object.

Return Value

An object. Returns the new IXMLDOMProcessingInstruction object.

Example

The following script example specifies the target string XML and data string version = "1.0" to generate the processing instruction <?XML version="1.0"?>.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var pi;
xmlDoc.async = false;
xmlDoc.load("books.xml");
pi = xmlDoc.createProcessingInstruction("xml", "version=\"1.0\"");
xmlDoc.insertBefore(pi, xmlDoc.childNodes.item(0));
alert(xmlDoc.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMProcessingInstruction =
oXMLDOMDocument.createProcessingInstruction(target, data)

Parameters

target
A string specifying the target part of the processing instruction. This supplies the nodeName property of the new object.
data
A string specifying the rest of the processing instruction preceding the closing ?> characters. This supplies the nodeValue property for the new object.

Return Value

An object. Returns the new IXMLDOMProcessingInstruction object.

Example

The following Microsoft® Visual Basic® example specifies the target string XML and data string version = "1.0" to generate the processing instruction <?XML version="1.0"?>.

Dim xmlDoc As New Msxml2.DOMDocument
Dim pi As IXMLDOMProcessingInstruction
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set pi = xmlDoc.createProcessingInstruction("xml", "version=""1.0""")
xmlDoc.insertBefore pi, xmlDoc.childNodes.Item(0)
MsgBox (xmlDoc.xml)
[C/C++]

C/C++ Syntax

HRESULT createProcessingInstruction(
    BSTR target,
    BSTR data,
    IXMLDOMProcessingInstruction **pi);

Parameters

target [in]
The target part of the processing instruction. It supplies the nodeName property of the new object.
data [in]
The remainder of the processing instruction preceding the closing ?> characters. It supplies the nodeValue property for the new object.
pi [out, retval]
The address of the new IXMLDOMProcessingInstruction object.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if pi is Null.
E_FAIL
The value returned if an error occurs.

Remarks

Creating a processing instruction node with this method is the same as using createNode where the type parameter value is NODE_PROCESSING_INSTRUCTION and no namespace is specified. You cannot specify a namespace with the createProcessingInstruction method.

Although this method creates the new object in the context of this document, it does not automatically add the new object to the document tree. In other words, although the ownerDocument property of the new node points to this document object, the parentNode property is set to Null. To add the new object, you must explicitly call one of the node insert methods, insertBefore method, replaceChild method, or appendChild method.

The new object's nodeType property has the value NODE_PROCESSING_INSTRUCTION.

See Also

nodeName Property | nodeType Property | nodeValue Property | IXMLDOMProcessingInstruction | createNode Method | ownerDocument Property | insertBefore Method | replaceChild Method | appendChild Method

Applies to: DOMDocument


createProcessor Method

Creates a rental-model IXSLProcessor object that will use this template.

[Script]

Script Syntax

var objXSLProcessor = objXSLTemplate.createProcessor();

Example

var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xslProc;
xslDoc.async = false;
xslDoc.load("sample.xsl");
xslt.stylesheet = xslDoc;
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
xslProc = xslt.createProcessor();
xslProc.input = xmlDoc;
xslProc.addParameter("param1", "Hello");
xslProc.transform();
alert(xslProc.output);

File Name: Sample.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      The parameter value was: <xsl:value-of select="$param1"/>
  </xsl:template>
</xsl:stylesheet>
[Visual Basic]

Visual Basic Syntax

Set objXSLProcessor = objXSLTemplate.createProcessor

Example

Dim xslt As New Msxml2.XSLTemplate
Dim xslDoc As New Msxml2.FreeThreadedDOMDocument
Dim xmlDoc As New Msxml2.DOMDocument
Dim xslProc As IXSLProcessor
xslDoc.async = False
xslDoc.Load "sample.xsl"
Set xslt.stylesheet = xslDoc
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set xslProc = xslt.createProcessor()
xslProc.input = xmlDoc
xslProc.addParameter "param1", "Hello"
xslProc.Transform
MsgBox xslProc.output

File Name: Sample.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      The parameter value was: <xsl:value-of select="$param1"/>
  </xsl:template>
</xsl:stylesheet>
[C/C++]

C/C++ Syntax

HRESULT createProcessor(IXSLProcessor** ppProcessor);

Parameters

ppProcessor [out, retval]
The returned processor associated with this template.

C/C++ Return Values

E_OUTOFMEMORY

E_FAIL
The value returned if the template has no style sheet.

Remarks

Multiple processors can be created from the same IXSLTemplate object.

See Also

Applies to: IXSLTemplate


createTextNode Method

Creates a text node that contains the supplied data.

[Script]

Script Syntax

var objXMLDOMText = oXMLDOMDocument.createTextNode(data);

Parameters

data
A string specifying the value to be supplied to the new text object's nodeValue property.

Return Value

An object. Returns the new IXMLDOMText object.

Example

The following script example creates an IXMLDOMText object, and then uses the insertBefore method to place it before the first child node of the document.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var MyText;
var MyNewNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
MyText = xmlDoc.createTextNode("Hello World");
MyNewNode = root.insertBefore(MyText, root.childNodes.item(0));
alert(xmlDoc.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMText = oXMLDOMDocument.createTextNode(data)

Parameters

data
A string specifying the value to be supplied to the new text object's nodeValue property.

Return Value

An object. Returns the new IXMLDOMText object.

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMText object, and then uses the insertBefore method to place it before the first child node of the document.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim MyText As IXMLDOMText
Dim MyNewNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
Set MyText = xmlDoc.createTextNode("Hello World")
Set MyNewNode = root.insertBefore(MyText, root.childNodes.Item(0))
MsgBox (xmlDoc.xml)
[C/C++]

C/C++ Syntax

HRESULT createTextNode(
    BSTR data,
    IXMLDOMText **text);

Parameters

data [in]
The value to be supplied to the new text's nodeValue.
text [out, retval]
The address of new IXMLDOMText.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if text is Null.
E_FAIL
The value returned if an error occurs.

Remarks

Creating a text node with this method is the same as using createNode where the type parameter value is NODE_TEXT and no namespace is specified. You cannot specify a namespace with the createTextNode method.

Although this method creates the new object in the context of this document, it does not automatically add the new object to the document tree. (In other words, although the ownerDocument property of the new node points to this document object, the parentNode property is set to Null.) To add the new object, you must explicitly call one of the node insert methods, insertBefore method, replaceChild method, or appendChild method.

The new nodeType property has the value NODE_TEXT.

See Also

nodeValue Property | IXMLDOMText | createNode Method | ownerDocument Property | parentNode Property | nodeType Property | insertBefore Method | replaceChild Method | appendChild Method

Applies to: DOMDocument


deleteData Method

Deletes specified data.

[Script]

Script Syntax

oXMLDOMCharacterData.deleteData(offset, count);

Parameters

offset
A long integer value specifying the offset, in characters, at which to start deleting string data.
count
A long integer value specifying the number of characters to delete.

Example

The following script example creates an IXMLDOMComment object and uses the deleteData method to delete the last six characters.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var comment;
xmlDoc.async = false;
xmlDoc.load("books.xml");
comment = xmlDoc.createComment("Hello World!");
comment.deleteData(6, 6);
alert(comment.xml);
[Visual Basic]

Visual Basic Syntax

oXMLDOMCharacterData.deleteData(offset, count)

Parameters

offset
A long integer value specifying the offset, in characters, at which to start deleting string data.
count
A long integer value specifying the number of characters to delete.

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMComment object and uses the deleteData method to delete the last six characters.

Dim xmlDoc As New Msxml2.DOMDocument
Dim comment As IXMLDOMComment
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set comment = xmlDoc.createComment("Hello World!")
comment.deleteData 6, 6
MsgBox (comment.xml)
[C/C++]

C/C++ Syntax

HRESULT deleteData(
    long offset,
    long count);

Parameters

offset [in]
The offset, in characters, at which to start deleting string data.
count [in]
The number of characters to delete.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value when returning Null.
E_FAIL
The value returned if an error occurs.

Remarks

If the offset and count of characters specify a range beyond the end of the string, this method deletes only to the end of the string.

The length property is updated by this operation.

See Also

length Property (IXMLDOMCharacterData)

Applies to: IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | IXMLDOMText


depth Method

Returns the depth within the document tree at which the specified node appears.

[Script]

Script Syntax

lValue = oXTLRuntime.depth(pNode);

Parameters

pNode
An object. The node for which the depth is to be returned.

Return Value

A long integer. The document element, or root node, returns the value "0"; its children return the value "1", and so on.

[Visual Basic]

Visual Basic Syntax

lValue = oXTLRuntime.depth(pNode)

Parameters

pNode
An object. The node for which the depth is to be returned.

Return Value

A long integer. The document element, or root node, returns the value "0"; its children return the value "1", and so on.

[C/C++]

C/C++ Syntax

HRESULT depth(IXMLDOMNode* pNode, long* pDepth);

Parameters

pNode [in]
The node for which the depth is to be returned.
pDepth [out, retval]
The depth within the document tree at which the specified node appears. The documentElement, or root node, returns the value "0", its children return the value "1", and so on.

C/C++ Return Values

S_OK
The value returned if successful.

See Also

Applies to: IXTLRuntime


formatDate Method

Formats the date using the specified formatting options.

[Script]

Script Syntax

strValue = oXTLRuntime.formatDate(varDate, bstrFormat, varDestLocale);

Parameters

varDate
A variant. The date that is to be formatted.
bstrFormat
A string. The specified formatting. See Remarks.
varDestLocale [optional]
A variant. The locale to use in determining the correct sequence to be employed in the date. If not supplied, the month-day-year sequence is used.

Return Value

A string. Returns the string containing the date in the requested format.

The formatDate method is derived from the Win32 application programming interface (API) call, GetDateFormat.

Example

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="Sample.xsl"?>
<XMLSamples xml:space="preserve"
         xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <FileDetails>
   <Author>Robert Brown</Author>
   <Date dt:dt="datetime">2000-02-16T15:56:00</Date>
  </FileDetails>
</XMLSamples>

File Name: Sample.xsl

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"
      xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <xsl:template match="/">
  <HTML>
  <HEAD>
  </HEAD>
  <BODY>
   <xsl:for-each select="XMLSamples/FileDetails/Date">
   Date Edited :
<xsl:eval>
formatDate(this.nodeTypedValue, "MMM dd, yyyy");
</xsl:eval>
   </xsl:for-each>
  </BODY>
  </HTML>
</xsl:template>
</xsl:stylesheet>

Output

Date Edited : Feb 16, 2000
[Visual Basic]

Visual Basic Syntax

strValue = oXTLRuntime.formatDate(varDate, bstrFormat, varDestLocale)

Parameters

varDate
A variant. The date that is to be formatted.
bstrFormat
A string. The specified formatting. See Remarks.
varDestLocale [optional]
A variant. The locale to use in determining the correct sequence to be employed in the date. If not supplied, the month-day-year sequence is used.

Return Value

A string. Returns the string containing the date in the requested format.

The formatDate method is derived from the Win32 application programming interface (API) call, GetDateFormat.

Example

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="Sample.xsl"?>
<XMLSamples xml:space="preserve"
         xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <FileDetails>
   <Author>Robert Brown</Author>
   <Date dt:dt="datetime">2000-02-16T15:56:00</Date>
  </FileDetails>
</XMLSamples>

File Name: Sample.xsl

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"
      xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <xsl:template match="/">
  <HTML>
  <HEAD>
  </HEAD>
  <BODY>
   <xsl:for-each select="XMLSamples/FileDetails/Date">
   Date Edited :
<xsl:eval>
formatDate(this.nodeTypedValue, "MMM dd, yyyy");
</xsl:eval>
   </xsl:for-each>
  </BODY>
  </HTML>
</xsl:template>
</xsl:stylesheet>

Output

Date Edited : Feb 16, 2000
[C/C++]

C/C++ Syntax

HRESULT formatDate(
    VARIANT varDate,
    BSTR bstrFormat,
    VARIANT varDestLocale,
    BSTR *pbstrFormattedString);

Parameters

varDate [in]
The date that is to be formatted.
bstrFormat [in]
The formatting specifics. See Remarks.
varDestLocale [in, optional]
A variant. The locale to use in determining the correct sequence to be employed in the date. If not supplied, the month-day-year sequence is used.
Note This parameter is not yet implemented.
pbstrFormattedString [out, retval]
A string containing the date in the requested format.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

The following are supported date codes.

M | Months as 1–12
MM | Months as 01–12
MMM | Months as Jan–Dec
MMMM | Months as January–December
MMMMM | Months as the first letter of the month
d | Days as 1–31
dd | Days as 01–31
ddd | Days as Sun–Sat
dddd | Days as Sunday–Saturday
yy | Years as 00–99
yyyy | Years as 1900–9999

See Also

Applies to: IXTLRuntime

Other Resources Other Resources

Formatted Date and Time Strings


formatIndex Method

Formats the index integer using the specified numerical system.

[Script]

Script Syntax

strValue = oXTLRuntime.formatIndex(lIndex, bstrFormat);

Parameters

lIndex
A long integer. The integer value that is to be converted.
bstrFormat
A string. The specified numbering system. See Remarks.

Return Value

A string. Returns the integer value formatted using the specified numbering system.

[Visual Basic]

Visual Basic Syntax

strValue = oXTLRuntime.formatIndex(lIndex, bstrFormat)

Parameters

lIndex
A long integer. The integer value that is to be converted.
bstrFormat
A string. The specified numbering system. See Remarks.

Return Value

A string. Returns the integer value formatted using the specified numbering system.

[C/C++]

C/C++ Syntax

HRESULT formatIndex(
    long lIndex,
    BSTR bstrFormat,
    BSTR *pbstrFormattedString);

Parameters

lIndex [in]
The integer value that is to be converted.
bstrFormat [in]
The numbering system. See Remarks.
pbstrFormattedString [out, retval]
The integer value formatted using the specified numbering system.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

Specified numerical system supports the following formats.

1 | Standard numbering system
01 | Standard numbering with leading zeroes
A | Uppercase sequence: A–Z, AA–ZZ
a | Lowercase sequence: a–z, aa–zz
I | Uppercase Roman numerals: I, II, III, IV, ...
i | Lowercase Roman numerals: i, ii, iii, iv, ...

See Also

Applies to: IXTLRuntime


formatNumber Method

Formats the number using the specified format.

[Script]

Script Syntax

strValue = oXTLRuntime.formatNumber(dblNumber, bstrFormat);

Parameters

dblNumber
A double. The number to be formatted.
bstrFormat
A string. The specified formatting characteristics to be applied to the number. See Remarks.

Return Value

A string. Returns a string containing the formatted number.

[Visual Basic]

Visual Basic Syntax

strValue = oXTLRuntime.formatNumber(dblNumber, bstrFormat)

Parameters

dblNumber
A double. The number to be formatted.
bstrFormat
A string. The specified formatting characteristics to be applied to the number. See Remarks.

Return Value

A string. Returns a string containing the formatted number.

[C/C++]

C/C++ Syntax

HRESULT formatNumber(
    double dblNumber,
    BSTR bstrFormat,
    BSTR *pbstrFormattedString);

Parameters

dblNumber [in]
The number to be formatted.
bstrFormat [in]
The formatting characteristics to be applied to the number. See Remarks.
pbstrFormattedString [out, retval]
The string containing the formatted number.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

Specified formatting characteristics that are applied to the number. Zero or more of the following values can be present.

# | Display only significant digits; does not display insignificant zeros.
0 (zero) | Display insignificant zeros if a number has fewer digits than there are zeros in the format.
? | Add spaces for insignificant zeros on either side of the decimal point so that decimal points align with a fixed-point font. You can also use this symbol for fractions that have varying numbers of digits.
. | Indicate the placement of the decimal point within the format.
, | Display a comma as a thousands separator or scale a number by a multiple of one thousand.
% | Display a number as a percentage of 100.
E- | (Also "e-") Display a number in scientific format (exponential notation). If a format contains a zero (0) or a number sign (#) to the right of an exponent code, display the number in scientific format and inserts an "E" or "e." The number of zeros or number signs to the right determines the number of digits in the exponent. Place a minus sign by negative exponents.
E+ | (Also "e+") Place a plus sign by positive exponents.

See Also

Applies to: IXTLRuntime


formatTime Method

Formats the time using the specified formatting options.

[Script]

Script Syntax

strValue = oXTLRuntime.formatTime(varTime, bstrFormat, varDestLocale);

Parameters

varTime
A variant. The time value that is to be formatted.
bstrFormat
A string. The specified formatting to be applied to the time. See Remarks.
varDestLocale [optional]
A variant. The locale to use in determining the correct sequence to be employed in the time.

Return Value

A string. Returns the string containing the time in the requested format.

Example

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="Sample.xsl"?>
<XMLSamples xml:space="preserve"
         xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <FileDetails>
   <Author>Robert Brown</Author>
   <Date dt:dt="datetime">2000-02-16T15:56:00</Date>
  </FileDetails>
</XMLSamples>

File Name: Sample.xsl

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"
      xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <xsl:template match="/">
  <HTML>
  <HEAD>
  </HEAD>
  <BODY>
   <xsl:for-each select="XMLSamples/FileDetails/Date">
   Time Edited :
<xsl:eval>
formatTime(this.nodeTypedValue, "hh:mm:ss");
</xsl:eval>
   </xsl:for-each>
  </BODY>
  </HTML>
</xsl:template>
</xsl:stylesheet>

Output

Time Edited : 03:56:00
[Visual Basic]

Visual Basic Syntax

strValue = oXTLRuntime.formatTime(varTime, bstrFormat, varDestLocale)

Parameters

varTime
A variant. The time value that is to be formatted.
bstrFormat
A string. The specified formatting to be applied to the time. See Remarks.
varDestLocale [optional]
A Variant. The locale to use in determining the correct sequence to be employed in the time.

Return Value

A string. Returns the string containing the time in the requested format.

Example

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="Sample.xsl"?>
<XMLSamples xml:space="preserve"
         xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <FileDetails>
   <Author>Robert Brown</Author>
   <Date dt:dt="datetime">2000-02-16T15:56:00</Date>
  </FileDetails>
</XMLSamples>

File Name: Sample.xsl

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"
      xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <xsl:template match="/">
  <HTML>
  <HEAD>
  </HEAD>
  <BODY>
   <xsl:for-each select="XMLSamples/FileDetails/Date">
   Time Edited :
<xsl:eval>
formatTime(this.nodeTypedValue, "hh:mm:ss");
</xsl:eval>
   </xsl:for-each>
  </BODY>
  </HTML>
</xsl:template>
</xsl:stylesheet>

Output

Time Edited : 03:56:00
[C/C++]

C/C++ Syntax

HRESULT formatTime(
    VARIANT varTime,
    BSTR bstrFormat,
    VARIANT varDestLocale,
    BSTR *pbstrFormattedString);

Parameters

varTime [in]
The time value that is to be formatted.
bstrFormat [in]
The formatting to be applied to the time. See Remarks.
varDestLocale [in, optional]
A variant. The locale to use in determining the correct sequence to be employed in the time.
pbstrFormattedString [out, retval]
A string containing the time in the requested format.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

The following codes are supported for time formats.

h | Hours as 0-23
hh | Hours as 00-23
m | Minutes as 0-59
mm | Minutes as 00-59
s | Seconds as 0-59
ss | Seconds as 00-59
AM/PM | Insert AM or PM, display hours as 12-hour clock
am/pm | Insert am or pm, display hours as 12-hour clock
A/P | Insert A or P, display hours as 12-hour clock
a | Insert a or p, display hours as 12-hour clock
[h]:mm | Elapsed time in hours; for example, 25.02
[mm]:ss | Elapsed time in minutes; for example, 63:46
[ss] | Elapsed time in seconds
ss.00 | Fractions of a second

See Also

Applies to: IXTLRuntime


get Method

Returns a read-only XML Document Object Model (DOM) node that contains the <Schema> element.

[Script]

Script Syntax

var objXMLDOMNode = objXMLDOMSchemaCol.get(namespaceURI);

Parameters

namespaceURI
The namespace URI associated with the schema to return.

This can be any string that can be used in an xmlns attribute, but it cannot contain entity references. The same white space normalization that occurs on the xmlns attribute also occurs on this argument (that is, leading and trailing white space is trimmed, new lines are converted to spaces, and multiple adjacent white space characters are collapsed into one space).

[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = objXMLDOMSchemaCol.get(namespaceURI)

Parameters

namespaceURI
The namespace URI associated with the schema to return.

This can be any string that can be used in an xmlns attribute, but it cannot contain entity references. The same white space normalization that occurs on the xmlns attribute also occurs on this argument (that is, leading and trailing white space is trimmed, new lines are converted to spaces, and multiple adjacent white space characters are collapsed into one space).

[C/C++]

C/C++ Syntax

HRESULT get(BSTR namespaceURI, IXMLDOMNode ** schemaNode);

Parameters

namespaceURI [in]
The namespace URI associated with the schema to return.

This may be any string that can be used in an xmlns attribute, but it cannot contain entity references. The same white space normalization that occurs on the xmlns attribute also occurs on this argument (that is, leading and trailing white space is trimmed, new lines are converted to spaces, and multiple adjacent white space characters are collapsed into one space).

schemaNode [out, retval]
A read-only IXMLDOMNode that represents the schema that is returned.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

This will not necessarily be the same document object provided by the add method, because the add method may have copied the schema. For inline schemas, this will apply directly to the <Schema> node embedded within the document.

See Also

add Method

Applies to: IXMLDOMSchemaCollection/XMLSchemaCache


getAllResponseHeaders Method (IXMLHTTPRequest)

Retrieves the values of all the HTTP headers.

[Script]

Script Syntax

strValue = oXMLHttpRequest.getAllResponseHeaders();

Return Value

A string. Contains the resulting header information.

Example

var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp.open("GET", "http://localhost/sample.xml", false);
xmlhttp.send();
alert(xmlhttp.getAllResponseHeaders());
[Visual Basic]

Visual Basic Syntax

strValue = oXMLHttpRequest.getAllResponseHeaders

Return Value

A string. Contains the resulting header information.

Example

Dim xmlhttp As New Msxml2.xmlhttp
xmlhttp.open "GET", "http://localhost/sample.xml", False
xmlhttp.send
MsgBox xmlhttp.getAllResponseHeaders()
[C/C++]

C/C++ Syntax

HRESULT getAllResponseHeaders(BSTR *pbstrHeaders);

Parameters

pbstrHeaders [out, retval]
The resulting header information.

C/C++ Return Values

S_OK
The value returned if successful.

C/C++ Example

HRESULT hr;
BSTR bstrValue = NULL;
IXMLHttpRequest *pIXMLHttpRequest = NULL;

try
{
   // Create XMLHttpRequest object and initialize pIXMLHttpRequest.
   hr = pIXMLHttpRequest->getAllResponseHeaders(&bstrValue);
   if(SUCCEEDED(hr))
      ::MessageBox(NULL, bstrValue, _T("All Response Headers"), MB_OK);
}
catch(...)
{
   DisplayErrorToUser();
}
// Release pIXMLHttpRequest when finished with it.

Remarks

Each header name/value pair is separated by a combination carriage return-linefeed character (vbCrLf in Microsoft® Visual Basic®).

The results of this method are valid only after the send method has been successfully completed.

See Also

send Method (IXMLHTTPRequest) | getResponseHeader Method (IXMLHTTPRequest) | setRequestHeader Method (IXMLHTTPRequest)

Applies to: IXMLHTTPRequest


getAllResponseHeaders Method (ServerXMLHTTP/IServerXMLHTTPRequest)

Retrieves the values of all the HTTP headers.

[Script]

Script Syntax

strValue = oServerXMLHTTPRequest.getAllResponseHeaders();

Example

var xmlServerHttp = new ActiveXObject("Msxml2.ServerXMLHTTP");
xmlServerHttp.open("GET", "http://localhost/sample.xml", false);
xmlServerHttp.send();
alert(xmlServerHttp.getAllResponseHeaders());
[Visual Basic]

Visual Basic Syntax

strValue = oServerXMLHTTPRequest.getAllResponseHeaders

Example

Dim xmlServerHttp As New Msxml2.ServerXMLHTTP
xmlServerHttp.open "GET", "http://localhost/sample.xml", False
xmlServerHttp.send
MsgBox xmlServerHttp.getAllResponseHeaders()
[C/C++]

C/C++ Syntax

HRESULT getAllResponseHeaders(BSTR *pbstrHeaders);

Parameters

pbstrHeaders [out, retval]
The resulting header information.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

Each header name/value pair is separated by a combination carriage return–linefeed character (vbCrLf in Microsoft® Visual Basic®).

The results of this method are valid only after the send method has been successfully completed.

See Also

send Method (ServerXMLHTTP/IServerXMLHTTPRequest) | getResponseHeader Method (ServerXMLHTTP/IServerXMLHTTPRequest) | setRequestHeader Method (ServerXMLHTTP/IServerXMLHTTPRequest)

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


getAttribute Method

Gets the value of the attribute.

[Script]

Script Syntax

objValue = oXMLDOMElement.getAttribute(name);

Parameters

name
A string specifying the name of the attribute to return.

Return Value

A variant. Returns a string that contains the attribute value or returns the empty string if the named attribute does not have a specified or default value.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeBook, sIdValue;
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodeBook = xmlDoc.selectSingleNode("//book");
sIdValue = nodeBook.getAttribute("id")
alert(sIdValue);
[Visual Basic]

Visual Basic Syntax

objValue = oXMLDOMElement.getAttribute(name)

Parameters

name
A string specifying the name of the attribute to return.

Return Value

A variant. Returns a string that contains the attribute value or returns the empty string if the named attribute does not have a specified or default value.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeBook As IXMLDOMElement
Dim sIdValue As String
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodeBook = xmlDoc.selectSingleNode("//book")
sIdValue = nodeBook.getAttribute("id")
MsgBox sIdValue
[C/C++]

C/C++ Syntax

HRESULT getAttribute(
    BSTR name,
    VARIANT *value);

Parameters

name [in]
The name of the attribute to return.
value [out, retval]
The string that contains the attribute value. The empty string is returned if the named attribute does not have a specified or default value.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value when no attribute with the given name is found.
E_INVALIDARG
The value returned if name is Null.

C/C++ Example

BOOL DOMElementAttribute()
{
   BOOL bResult = FALSE;
   _variant_t varValue;
   BSTR bstrAttributeName = ::SysAllocString(_T("dateCreated"));
   IXMLDOMDocument *pIXMLDOMDocument = NULL;
   IXMLDOMElement *pIXMLDOMElement = NULL;
   HRESULT hr;

   try
   {
      // Create an instance of DOMDocument and initialize
      // pIXMLDOMDocument.
      // Load/create an XML fragment.
      hr = pIXMLDOMDocument->get_documentElement(&pIXMLDOMElement);
      SUCCEEDED(hr) ? 0 : throw hr;

      If(pIXMLDOMElement)
      {
         varValue = _T("year 2000");
         hr = pIXMLDOMElement->setAttribute(bstrAttributeName, varValue);
         SUCCEEDED(hr) ? 0 : throw hr;

         hr = pIXMLDOMElement->getAttribute(bstrAttributeName, &varValue);
         SUCCEEDED(hr) ? 0 : throw hr;
         if(varValue.vt != VT_NULL)
         {
            ::MessageBox(NULL, _bstr_t(varValue), bstrAttributeName, MB_OK);
            bResult = TRUE;
         }
         ::SysFreeString(bstrAttributeName);
         bstrAttributeName = NULL;
         pIXMLDOMElement->Release();
      }
   }
   catch(...)
   {
      if(bstrAttributeName)
         ::SysFreeString(bstrAttributeName);
      if(pIXMLDOMElement)
         pIXMLDOMElement->Release();
      DisplayErrorToUser();
   }
   return bResult;
}

Remarks

You can also retrieve attributes by using the getNamedItem method of the IXMLDOMNamedNodeMap.

See Also

getNamedItem Method | IXMLDOMNamedNodeMap

Applies to: IXMLDOMElement


getAttributeNode Method

Gets the attribute node.

[Script]

Script Syntax

var objXMLDOMAttribute = oXMLDOMElement.getAttributeNode(name);

Parameters

name
The string specifying the name of the attribute to be retrieved.

Return Value

An object. Returns IXMLDOMAttribute with the supplied name, or Null if the named attribute cannot be found on this element.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeBook, nodeId, sIdValue;
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodeBook = xmlDoc.selectSingleNode("//book");
nodeId = nodeBook.getAttributeNode("id");
sIdValue = nodeId.value;
alert(sIdValue);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMAttribute = oXMLDOMElement.getAttributeNode(name)

Parameters

name
The string specifying the name of the attribute to be retrieved.

Return Value

An object. Returns IXMLDOMAttribute with the supplied name, or Null if the named attribute cannot be found on this element.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeBook As IXMLDOMElement
Dim nodeId As IXMLDOMAttribute
Dim sIdValue As String
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodeBook = xmlDoc.selectSingleNode("//book")
Set nodeId = nodeBook.getAttributeNode("id")
sIdValue = nodeId.Value
MsgBox sIdValue
[C/C++]

C/C++ Syntax

HRESULT getAttributeNode(
    BSTR name,
    IXMLDOMAttribute **attributeNode);

Parameters

name [in]
The name of the attribute to be retrieved.
attributeNode [out, retval]
An IXMLDOMAttribute object that is returned with the supplied name, or Null if the named attribute cannot be found on this element.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned when no attribute with the given name is found.
E_INVALIDARG
The value returned if name is Null.

C/C++ Example

BOOL DOMElementAttributeNode()
{
   BOOL bResult = FALSE;
   BSTR bstrAttributeName = ::SysAllocString(_T("dateCreated"));
   IXMLDOMAttribute* pIXMLDOMAttribute = NULL;
   IXMLDOMElement *pIXMLDOMElement = NULL;
   IXMLDOMDocument *pIXMLDOMDocument = NULL;
   HRESULT hr;

   try
   {
      // Create an instance of DOMDocument and initialize
      // pIXMLDOMDocument.
      // Load/create an XML fragment.
      hr = pIXMLDOMDocument->get_documentElement(&pIXMLDOMElement);
      SUCCEEDED(m_hr) ? 0 : throw hr;

      If(pIXMLDOMElement)
      {
         hr = pIXMLDOMElement->getAttributeNode(bstrAttributeName, &pIXMLDOMAttribute);
         if(SUCCEEDED(hr) && pIXMLDOMAttribute)
         {
         // Read node value and display . . .
            bResult = TRUE;
            pIXMLDOMAttribute->Release();
            pIXMLDOMAttribute = NULL;
         }
         ::SysFreeString(bstrAttributeName);
         bstrAttributeName = NULL;
         pIXMLDOMElement->Release();
         pIXMLDOMElement = NULL;
      }
   }
   catch(...)
   {
      if(bstrAttributeName)
         ::SysFreeString(bstrAttributeName);
      if(pIXMLDOMAttribute)
         pIXMLDOMAttribute->Release();
      if(pIXMLDOMElement)
         pIXMLDOMElement->Release();
      DisplayErrorToUser();
   }
   return bResult;
}

See Also

IXMLDOMAttribute

Applies to: IXMLDOMElement


getElementsByTagName Method (DOMDocument)

Returns a collection of elements that have the specified name.

[Script]

Script Syntax

var objXMLDOMNodeList =
    oXMLDOMDocument.getElementsByTagName(tagName);

Parameters

tagName
A string specifying the element name to find. The tagName "*" returns all elements in the document.

Return Value

An object. Points to a collection of elements that match the specified name.

Example

The following script example creates an IXMLDOMNodeList object using the DOMDocument object's getElementsByTagName method, and then displays all of the elements with the desired tag name.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var objNodeList;
xmlDoc.async = false;
xmlDoc.load("books.xml");
objNodeList = xmlDoc.getElementsByTagName("author");
for (var i=0; i<objNodeList.length; i++) {
  alert(objNodeList.item(i).xml);
}
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNodeList =
    oXMLDOMDocument.getElementsByTagName(tagName)

Parameters

tagName
A string specifying the element name to find. The tagName "*" returns all elements in the document.

Return Value

An object. Points to a collection of elements that match the specified name.

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNodeList object using the DOMDocument object's getElementsByTagName method, and then displays all of the elements with the desired tag name.

Dim xmlDoc As New Msxml2.DOMDocument
Dim objNodeList As IXMLDOMNodeList
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set objNodeList = xmlDoc.getElementsByTagName("author")
For i = 0 To (objNodeList.length - 1)
  MsgBox (objNodeList.Item(i).xml)
Next
[C/C++]

C/C++ Syntax

HRESULT getElementsByTagName(
    BSTR tagName,
    IXMLDOMNodeList **resultList);

Parameters

tagName [in]
The element name to find. The tag name "*" returns all elements in the document.
resultList [out, retval]
The address of a collection of elements that match the specified name.

C/C++ Return Values

S_OK
The value returned if successful.

Example

IXMLDOMDocument *pIXMLDOMDocument = NULL;
wstring strFindText (_T("author"));
IXMLDOMNodeList *pIDOMNodeList = NULL;
IXMLDOMNode *pIDOMNode = NULL;
long value;
BSTR bstrItemText;
HRESULT hr;

try
{
   // Initialize pIXMLDOMDocument (create a DOMDocument).
   // Load document.
   hr = pIXMLDOMDocument->getElementsByTagName(
            (TCHAR*)strFindText.data(), &pIDOMNodeList);
   SUCCEEDED(hr) ? 0 : throw hr;

   hr = pIDOMNodeList->get_length(&value);
   if(SUCCEEDED(hr))
   {
      pIDOMNodeList->reset();
      for(int ii = 0; ii < value; ii++)
      {
         pIDOMNodeList->get_item(ii, &pIDOMNode);
         if(pIDOMNode )
         {
            pIDOMNode->get_text(&bstrItemText);
            ::MessageBox(NULL, bstrItemText,strFindText.data(), MB_OK);
            pIDOMNode->Release();
            pIDOMNode = NULL;
         }
      }
   }
   pIDOMNodeList->Release();
   pIDOMNodeList = NULL;
}
catch(...)
{
   if(pIDOMNodeList)
      pIDOMNodeList->Release();
   if(pIDOMNode)
      pIDOMNode->Release();
   DisplayErrorToUser();
}
// Release pIXMLDOMDocument when finished with it.

Remarks

The elements in the collection are returned in the order in which they would be encountered in a preorder traversal of the document tree. In a preorder traversal, the parent root node is visited first and each child node from left to right is then traversed.

The returned IXMLDOMNodeList object is live and immediately reflects changes to the nodes that appear in the list.

More complex searches can be performed using the selectNodes method. This method can also be faster in some cases.

See Also

IXMLDOMNodeList | selectNodes Method

Applies to: DOMDocument


getElementsByTagName Method (IXMLDOMElement)

Returns a list of all descendant elements that match the supplied name.

[Script]

Script Syntax

var objXMLDOMNodeList = oXMLDOMElement.getElementsByTagName(tagName);

Parameters

tagName
A string specifying the name of the element to find. The string "*" matches all descendant elements of this element.

Return Value

An object. Returns IXMLDOMNodeList object containing all elements that match the supplied name.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeBook, nodelistAuthor;
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodeBook = xmlDoc.selectSingleNode("//book");
nodelistAuthor = nodeBook.getElementsByTagName("author");
alert(nodelistAuthor.length);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNodeList = oXMLDOMElement.getElementsByTagName(tagName)

Parameters

tagName
A string specifying the name of the element to find. The string "*" matches all descendant elements of this element.

Return Value

An object. Returns IXMLDOMNodeList object containing all elements that match the supplied name.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeBook As IXMLDOMElement
Dim nodelistAuthor As IXMLDOMNodeList
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodeBook = xmlDoc.selectSingleNode("//book")
Set nodelistAuthor = nodeBook.getElementsByTagName("author")
MsgBox nodelistAuthor.length
[C/C++]

C/C++ Syntax

HRESULT getElementsByTagName(
    BSTR tagName,
    IXMLDOMNodeList **resultList);

Parameters

tagName [in]
The name of the element to find. The string "*" matches all descendant elements of this element.
resultList [out, retval]
An IXMLDOMNodeList object containing all elements that match the supplied name.

C/C++ Return Values

S_OK
The value returned if successful.

C/C++ Example

// Find all Nodes with a particular tag
BOOL DOMDocFindNodesWithTag()
{
   BOOL bResult = FALSE;
   CString strFindText (_T("author"));
   IXMLDOMNodeList *pIDOMNodeList = NULL;
   IXMLDOMNode *pIDOMNode = NULL;
   long value = 0;
   BSTR bstrItemText = NULL;
   HRESULT hr;

   try
   {
      // Create the DOMDocument and initialise m_pIXMLDOMDocument2
      // find all "author" elements
      hr = m_pIXMLDOMDocument2->getElementsByTagName(
(TCHAR *)strFindText.GetBuffer(0),
&pIDOMNodeList);
      SUCCEEDED(hr) ? 0 : throw hr;

      // get the length of the list returned by the previous find
      hr = pIDOMNodeList->get_length(&value);
      if(SUCCEEDED(hr))
      {
         pIDOMNodeList->reset();
      // loop through the elements found and display the contents
         for(int ii = 0; ii < value; ii++)
         {
            hr = pIDOMNodeList->get_item(ii, &pIDOMNode);
            SUCCEEDED(hr) ? 0 : throw hr;
            if(pIDOMNode)
            {
               hr = pIDOMNode->get_text(&bstrItemText);
               SUCCEEDED(hr) ? 0 : throw hr;
               if(bstrItemText)
               {
                     bResult = TRUE;
                     ::MessageBox(NULL, bstrItemText, strFindText, MB_OK);
                     ::SysFreeString(bstrItemText);
                     bstrItemText = NULL;
               }
               pIDOMNode->Release();
               pIDOMNode = NULL;
            }
         }
         pIDOMNodeList->Release();
         pIDOMNodeList = NULL;
      }
   }
   catch(...)
   {
      if(pIDOMNodeList)
         pIDOMNodeList->Release();
      if(pIDOMNode)
         pIDOMNode->Release();
      if(bstrItemText)
         ::SysFreeString(bstrItemText);
      bResult = FALSE;
      DisplayErrorToUser();
   }

   return bResult;
}

Remarks

Elements appear in the order encountered in a preorder traversal of this element's tree.

The IXMLDOMNodeList object is returned even if there are no matches. In this case, the length of the list will be set to zero.

The IXMLDOMNodeList is live and immediately reflects changes to the nodes that appear in the list.

See Also

IXMLDOMNodeList

Applies to: IXMLDOMElement


getNamedItem Method

Retrieves the attribute with the specified name.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNamedNodeMap.getNamedItem(name);

Parameters

name
A string specifying the name of the attribute.

Return Value

An object. Returns IXMLDOMNode object for the specified attribute. Returns Null if the attribute node is not in this collection.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeBook, nodeId;
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodeBook = xmlDoc.selectSingleNode("//book");
nodeId = nodeBook.attributes.getNamedItem("id");
alert(nodeId.value);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNamedNodeMap.getNamedItem(name)

Parameters

name
A string specifying the name of the attribute.

Return Value

An object. Returns an IXMLDOMNode object for the specified attribute. Returns Null if the attribute node is not in this collection.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeBook As IXMLDOMElement
Dim nodeId As IXMLDOMAttribute
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodeBook = xmlDoc.selectSingleNode("//book")
Set nodeId = nodeBook.Attributes.getNamedItem("id")
MsgBox nodeId.Value
[C/C++]

C/C++ Syntax

HRESULT getNamedItem(
    BSTR name,
    IXMLDOMNode **namedItem);

Parameters

name [in]
The name of the attribute.
namedItem [out, retval]
An IXMLDOMNode object for the specified attribute. Returns Null if the attribute node is not in this collection.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value when returning Null.
E_INVALIDARG
The value returned if namedItem is Null.

C/C++ Example

IXMLDOMNode *pIXMLDOMNode = NULL;
IXMLDOMNamedNodeMap *pIXMLDOMNamedNodeMap = NULL;
BSTR bstrAttributeName = ::SysAllocString(_T("dateModified"));
IXMLDOMElement *pIXMLDOMElement = NULL;
IXMLDOMDocument *pIXMLDOMDocument = NULL;
VARIANT varValue;

try
{
   // Create an instance of DOMDocument and initialize pIXMLDOMDocument.
   // Load/create an XML fragment.
   hr = pIXMLDOMDocument->get_documentElement(&pIXMLDOMElement);
   SUCCEEDED(hr) ? 0 : throw hr;

   if(pIXMLDOMElement)
   {
      hr = pIXMLDOMElement->get_attributes(&pIXMLDOMNamedNodeMap);
      if(SUCCEEDED(hr) && pIXMLDOMNamedNodeMap)
      {
         hr = pIXMLDOMNamedNodeMap->getNamedItem(bstrAttributeName, &pIXMLDOMNode);
         if(SUCCEEDED(hr) && pIXMLDOMNode)
         {
            pIXMLDOMNode->get_nodeValue(&varValue);
            ::MessageBox(NULL, _bstr_t(varValue), _T("Item Value"), MB_OK);
            pIXMLDOMNode->Release();
            pIXMLDOMNode = NULL;
         }
         pIXMLDOMNamedNodeMap->Release();
         pIXMLDOMNamedNodeMap = NULL;
      }
      pIXMLDOMElement->Release();
      pIXMLDOMElement = NULL;
   }
   ::SysFreeString(bstrAttributeName);
   bstrAttributeName = NULL;
}
catch(...)
{
   if(bstrAttributeName)
      ::SysFreeString(bstrAttributeName);
   if(pIXMLDOMElement)
      pIXMLDOMElement->Release();
   if(pIXMLDOMNamedNodeMap)
      pIXMLDOMNamedNodeMap->Release();
   if(pIXMLDOMNode)
      pIXMLDOMNode->Release();
   DisplayErrorToUser();
}
// Release pIXMLDOMDocument when finished with it.

See Also

IXMLDOMNode

Applies to: IXMLDOMNamedNodeMap


getOption Method

Returns the value of one of the following options:

SXH_OPTION_URL_CODEPAGE
The code page used to convert the Unicode URL string specified in the open method.
SXH_OPTION_ESCAPE_PERCENT_IN_URL
The escaping of the % character.
SXH_OPTION_IGNORE_SERVER_SSL_CERT_ERROR_FLAGS
Flags that can be set to ignore problems with the server's Secure Sockets Layer (SSL) certificate.
SXH_OPTION_SELECT_CLIENT_SSL_CERT
The name of the client certificate specified in your local store.
[Script]

Script Syntax

varValue = oServerXMLHTTPRequest.getOption(option);

Parameters

option
The option whose value is to be returned. For a list of available options and a description of how to use those options, see Remarks.
[Visual Basic]

Visual Basic Syntax

varValue = oServerXMLHTTPRequest.getOption(option)
option
The option whose value is to be returned. For a list of available options and a description of how to use those options, see Remarks.
[C/C++]

C/C++ Syntax

HRESULT getOption(SERVERXMLHTTP_OPTION option, VARIANT * value);

Parameters

option [in]
The option whose value is to be returned. For a list of available options and a description of how to use those options, see Remarks.
value [out, retval]
The return value of the option.

C/C++ Return Values

S_OK
Value returned if successful.

Remarks

The following table lists the options available for the getOption method.

Option Description
0 SXH_OPTION_URL_CODEPAGE

By default, CP_UTF8 is the code page used to convert the Unicode URL string (specified in the open method) to a single-byte representation.

The SXH_OPTION_URL_CODEPAGE option allows the client to override this default with a different code page value. The client should specify an unsigned integer value for the code page.
1 SXH_OPTION_ESCAPE_PERCENT_IN_URL

By default, escaping unsafe ANSI characters in the URL (for example, " " -> "%20") does not escape the % character itself.

The SXH_OPTION_ESCAPE_PERCENT_IN_URL option allows the client to change this behavior. The client should specify a Boolean True/False value for this option.
2 SXH_OPTION_IGNORE_SERVER_SSL_CERT_ERROR_FLAGS

The SXH_OPTION_IGNORE_SERVER_SSL_CERT_ERROR_FLAGS option is a DWORD mask of various flags that can be set to change this default behavior. The default value is to ignore all problems. You must set this option before calling the send method. The flags are as follows:

SXH_SERVER_CERT_IGNORE_UNKNOWN_CA = 256

Unknown certificate authority

SXH_SERVER_CERT_IGNORE_WRONG_USAGE = 512

Malformed certificate such as a certificate with no subject name.

SXH_SERVER_CERT_IGNORE_CERT_CN_INVALID = 4096

Mismatch between the visited hostname and the certificate name being used on the server.

SXH_SERVER_CERT_IGNORE_CERT_DATE_INVALID = 8192

The date in the certificate is invalid or has expired.

SXH_SERVER_CERT_IGNORE_ALL_SERVER_ERRORS = 13056

All certificate errors.

To turn off a flag, you subtract it from the default value, which is the sum of all flags. For example, to catch an invalid date in a certificate, you turn off the SXH_SERVER_CERT_IGNORE_CERT_DATE_INVALID flag as follows:

shx.setOption(2) = (shx.getOption(2) _
                    - SXH_SERVER_CERT_IGNORE_CERT_DATE_INVALID)
3 SXH_OPTION_SELECT_CLIENT_SSL_CERT

By default, the value of this option is an empty string (""), which means pick the first certificate in the local store to send if the server requests a client certificate.

The SXH_OPTION_SELECT_CLIENT_SSL_CERT option is a string that lets you select which client certificate from the local store should be sent. You must set this option before calling the send method. The following example sets the client certificate option to request the client certificate named "MSXML":

certName = shx.getOption(3)

See Also

open Method (ServerXMLHTTP/IServerXMLHTTPRequest) | setOption Method

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


getProperty Method (IXMLDOMDocument2)

Returns the default properties.

[Script]

Script Syntax

strPropValue = objXMLDOMDocument2.getProperty(name);

Parameters

name
The string name of the property. This name is case-sensitive.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.setProperty("SelectionLanguage", "XPath");
alert(xmlDoc.getProperty("SelectionLanguage"));
[Visual Basic]

Visual Basic Syntax

strPropValue = objXMLDOMDocument2.getProperty(name)

Parameters

name
The string name of the property. This name is case-sensitive.

Example

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.setProperty "SelectionLanguage", "XPath"
MsgBox xmlDoc.getProperty("SelectionLanguage")
[C/C++]

C/C++ Syntax

HRESULT getProperty(BSTR name, VARIANT* value);

Parameters

name [in]
The string name of the property. This name is case-sensitive.
value [out, retval]
The variant return value of the requested flag.

C/C++ Return Values

S_OK
The value returned if successful.
E_FAIL
The value returned if property name is invalid.

See Also

Applies to: IXMLDOMDocument2


getProperty Method (IXMLDOMSelection)

Returns a property.

[Script]

Script Syntax

strValue = objXMLDOMSelection.getProperty(name);

Parameters

name
The string name of the property. This name is case-sensitive.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var oSelection;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.async = false;
xmlDoc.load("books.xml");
oSelection = xmlDoc.selectNodes("//book");
alert(oSelection.getProperty("SelectionLanguage"));
[Visual Basic]

Visual Basic Syntax

strValue = objXMLDOMSelection.getProperty(name)

Parameters

name
The string name of the property. This name is case-sensitive.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim oSelection As IXMLDOMSelection
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set oSelection = xmlDoc.selectNodes("//book")
MsgBox oSelection.getProperty("SelectionLanguage")
[C/C++]

C/C++ Syntax

HRESULT getProperty(BSTR name, VARIANT* value);

Parameters

name [in]
The string name of the property. This name is case-sensitive.
value [out, retval]
The variant return value of the requested property.

C/C++ Return Values

S_OK
The value returned if method successful.
E_INVALIDARG
The value returned if named property does not exist.

Remarks

The getProperty method returns the value for the internal SelectionLanguage property (flag) that was set by calling the setProperty method on the document or the default value.

See Also

setProperty Method

Applies to: IXMLDOMSelection


getQualifiedItem Method

Returns the attribute with the specified namespace and attribute name.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNamedNodeMap.getQualifiedItem(baseName, namespaceURI);

Parameters

baseName
The string specifying the base name of the attribute, without namespace qualification.
namespaceURI
The string specifying the namespace prefix that qualifies the attribute name.

Return Value

An object. Returns the attribute node specified by the baseName and namespaceURI parameters. Returns Null if the attribute is not in the collection or if the item is not an attribute.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var oNamedNodeMap, nodeBook;
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodeBook = xmlDoc.selectSingleNode("//book");
oNamedNodeMap = nodeBook.attributes;
alert(oNamedNodeMap.getQualifiedItem("id", "").value);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNamedNodeMap.getQualifiedItem(baseName, namespaceURI)

Parameters

baseName
The string specifying the base name of the attribute, without namespace qualification.
namespaceURI
The string specifying the namespace prefix that qualifies the attribute name.

Return Value

An object. Returns the attribute node specified by the baseName and namespaceURI parameters. Returns Null if the attribute is not in the collection or if the item is not an attribute.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim oNamedNodeMap As IXMLDOMNamedNodeMap
Dim nodeBook As IXMLDOMElement
Dim nodeId As IXMLDOMAttribute
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodeBook = xmlDoc.selectSingleNode("//book")
Set oNamedNodeMap = nodeBook.Attributes
Set nodeId = oNamedNodeMap.getQualifiedItem("id", "")
MsgBox nodeId.Value
[C/C++]

C/C++ Syntax

HRESULT getQualifiedItem(
    BSTR baseName,
    BSTR namespaceURI,
    IXMLDOMNode **qualifiedItem);

Parameters

baseName [in]
The base name of the attribute, without namespace qualification.
namespaceURI [in]
The namespace prefix that qualifies the attribute name.
qualifiedItem [out, retval]
The attribute node specified by the baseName and namespaceURI parameters. Returns Null if the attribute is not in the collection or if the item is not an attribute.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value when returning Null.
E_INVALIDARG
The value returned if qualifiedItem is Null.

C/C++ Example

IXMLDOMNode *pIXMLDOMNode = NULL;
IXMLDOMNamedNodeMap *pIXMLDOMNamedNodeMap = NULL;
BSTR bstrAttributeName = ::SysAllocString(_T("dateModified"));
IXMLDOMElement *pIXMLDOMElement = NULL;
VARIANT varValue;
IXMLDOMDocument *pIXMLDOMDocument = NULL;
HRESULT hr;

try
{
   // Create an instance of DOMDocument and initialize pIXMLDOMDocument.
   // Load/create an XML fragment.
   hr = pIXMLDOMDocument->get_documentElement(&pIXMLDOMElement);
   SUCCEEDED(hr) ? 0 : throw hr;

   if(pIXMLDOMElement)
   {
      hr = pIXMLDOMElement->get_attributes(&pIXMLDOMNamedNodeMap);
      if(SUCCEEDED(hr) && pIXMLDOMNamedNodeMap)
      {
         hr = pIXMLDOMNamedNodeMap->getQualifiedItem(bstrAttributeName, NULL, &pIXMLDOMNode);
         if(SUCCEEDED(hr) && pIXMLDOMNode)
         {
            pIXMLDOMNode->get_nodeValue(&varValue);
            ::MessageBox(NULL, _bstr_t(varValue), _T("Item Value"), MB_OK);
            pIXMLDOMNode->Release();
            pIXMLDOMNode = NULL;
         }
         pIXMLDOMNamedNodeMap->Release();
         pIXMLDOMNamedNodeMap = NULL;
      }
      pIXMLDOMElement->Release();
      pIXMLDOMElement = NULL;
   }
   ::SysFreeString(bstrAttributeName);
   bstrAttributeName = NULL;
}
catch(...)
{
   if(bstrAttributeName)
      ::SysFreeString(bstrAttributeName);
   if(pIXMLDOMElement)
      pIXMLDOMElement->Release();
   if(pIXMLDOMNamedNodeMap)
      pIXMLDOMNamedNodeMap->Release();
   if(pIXMLDOMNode)
      pIXMLDOMNode->Release();
   DisplayErrorToUser();
}
// Release pIXMLDOMDocument when finished with it.

Remarks

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

Applies to: IXMLDOMNamedNodeMap


getResponseHeader Method (IXMLHTTPRequest)

Retrieves the value of an HTTP header from the response body.

[Script]

Script Syntax

strValue = oXMLHttpRequest.getResponseHeader(bstrHeader);

Parameters

bstrHeader
A string containing the case-insensitive header name.

Return Value

A string. Contains the resulting header information.

Example

var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp.open("GET", "http://localhost/sample.xml", false);
xmlhttp.send();
alert(xmlhttp.getResponseHeader("Content-Length"));
[Visual Basic]

Visual Basic Syntax

strValue = oXMLHttpRequest.getResponseHeader(bstrHeader)

Parameters

bstrHeader
A string containing the case-insensitive header name.

Return Value

A string. Contains the resulting header information.

Example

Dim xmlhttp As New Msxml2.xmlhttp
xmlhttp.open "GET", "http://localhost/sample.xml", False
xmlhttp.send
MsgBox xmlhttp.getResponseHeader("Content-Length")
[C/C++]

C/C++ Syntax

HRESULT getResponseHeader(BSTR bstrHeader, BSTR* pbstrValue);

Parameters

bstrHeader [in]
A case-insensitive header name.
pbstrValue [out, retval]
The resulting header information.

C/C++ Return Values

S_OK
The value returned if successful.

C/C++ Example

HRESULT hr;
BSTR bstrValue = NULL;
IXMLHttpRequest *pIXMLHttpRequest = NULL;

try
{
   // Create XMLHttpRequest object and initialize pIXMLHttpRequest.
   hr = pIXMLHttpRequest->getResponseHeader(_T("Server"), &bstrValue);
   if(SUCCEEDED(hr))
   {
      ::MessageBox(NULL, m_bstrValue, _T("Response Header-Server"), MB_OK);
      ::SysFreeString(bstrValue);
      bstrValue = NULL;
   }
}
catch(...)
{
   if(bstrValue)
      ::SysFreeString(bstrValue);
   DisplayErrorToUser();
}
// Release pIXMLHttpRequest when finished with it.

Remarks

The results of this method are valid only after the send method has been successfully completed. The line, xmlhttp.getResponseHeader("Content-Type");, returns the string "text/xml", assuming the server set "text/xml" as the content type. The full list of header variables you can query can be accessed from the getAllResponseHeaders method.

See Also

getAllResponseHeaders Method (IXMLHTTPRequest) | send Method (IXMLHTTPRequest) | setRequestHeader Method (IXMLHTTPRequest)

Applies to: IXMLHTTPRequest


getResponseHeader Method (ServerXMLHTTP/IServerXMLHTTPRequest)

Retrieves the value of an HTTP header from the response body.

[Script]

Script Syntax

strValue = oServerXMLHTTPRequest.getResponseHeader(bstrHeader);

Parameters

bstrHeader
A case-insensitive header name.

Example

var xmlServerHttp = new ActiveXObject("Msxml2.ServerXMLHTTP");
xmlServerHttp.open("GET", "http://localhost/sample.xml", false);
xmlServerHttp.send();
alert(xmlServerHttp.getResponseHeader("Content-Length"));
[Visual Basic]

Visual Basic Syntax

strValue = oServerXMLHTTPRequest.getResponseHeader(bstrHeader)

Parameters

bstrHeader
A case-insensitive header name.

Example

Dim xmlServerHttp As New Msxml2.ServerXMLHTTP
xmlServerHttp.open "GET", "http://localhost/sample.xml", False
xmlServerHttp.send
MsgBox xmlServerHttp.getResponseHeader("Content-Length")
[C/C++]

C/C++ Syntax

HRESULT getResponseHeader(BSTR bstrHeader, BSTR* pbstrValue);

Parameters

bstrHeader [in]
A case-insensitive header name.
pbstrValue [out, retval]
The resulting header information.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

The results of this method are valid only after the send method has been successfully completed. The line, oServerXMLHTTPRequest.getResponseHeader("Content-Type"); returns the string "text/xml", assuming the server set "text/xml" as the content type.

The full list of header variables you can query can be accessed from the getAllResponseHeaders method.

See Also

getAllResponseHeaders Method(ServerXMLHTTP/IServerXMLHTTPRequest) | send Method (ServerXMLHTTP/IServerXMLHTTPRequest) | setRequestHeader Method (ServerXMLHTTP/IServerXMLHTTPRequest)

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


hasChildNodes Method

Provides a fast way to determine whether a node has children.

[Script]

Script Syntax

boolValue = oXMLDOMNode.hasChildNodes();

Return Value

Boolean. Returns True if this node has children.

Example

The following script example checks a node to see if it has any child nodes. If it does, it displays the number of child nodes it contains.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var currNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
currNode = xmlDoc.documentElement.firstChild;
if (currNode.hasChildNodes()) {
  alert(currNode.childNodes.length);
} else {
  alert("no child nodes");
}
[Visual Basic]

Visual Basic Syntax

boolValue = oXMLDOMNode.hasChildNodes

Return Value

Boolean. Returns True if this node has children.

Example

The following Microsoft® Visual Basic® example checks a node to see if it has any child nodes. If it does, it displays the number of child nodes it contains.

Dim xmlDoc As New Msxml2.DOMDocument
Dim currNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set currNode = xmlDoc.documentElement.firstChild
If currNode.hasChildNodes Then
  MsgBox currNode.childNodes.length
Else
  MsgBox "no child nodes"
End If
[C/C++]

C/C++ Syntax

HRESULT hasChildNodes(
    VARIANT_BOOL *hasChild);

Parameters

hasChild [out, retval]
Returns True if this node has children.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned when there are no children.
E_INVALIDARG
The value returned if hasChild is Null.

Remarks

It always returns False for nodes that, by definition, cannot have children: the IXMLDOMCDATASection, IXMLDOMComment, IXMLDOMNotation, IXMLDOMProcessingInstruction, and IXMLDOMText nodes.

See Also

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


hasFeature Method

Indicates support for the specified feature.

[Script]

Script Syntax

boolVal = objXMLDOMImplementation.hasFeature(feature, version);

Parameters

feature
A string that specifies the feature to test. In Level 1, valid feature values are "XML," "DOM," and "MS-DOM" (case-insensitive).
version
A string that specifies the version number to test, or if Null, tests for implementation of the feature in any version. In Level 1, "1.0" is the valid version value.

Return Value

Boolean. Returns True if the specified feature is implemented; otherwise False.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var bool = xmlDoc.implementation.hasFeature("DOM", "1.0");
alert(bool);
[Visual Basic]

Visual Basic Syntax

boolVal = objXMLDOMImplementation.hasFeature(feature, version)

Parameters

feature
A string that specifies the feature to test. In Level 1, valid feature values are "XML," "DOM," and "MS-DOM" (case-insensitive).
version
A string that specifies the version number to test, or if Null, tests for implementation of the feature in any version. In Level 1, "1.0" is the valid version value.

Return Value

Boolean. Returns True if the specified feature is implemented; otherwise False.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim bool As Boolean
bool = xmlDoc.implementation.hasFeature("DOM", "1.0")
MsgBox bool
[C/C++]

C/C++ Syntax

HRESULT hasFeature(
    BSTR feature,
    BSTR version,
    VARIANT_BOOL *hasFeature);

Parameters

feature [in]
The feature to test. In Level 1, valid feature values are "XML," "DOM," and "MS-DOM" (case-insensitive).
version [in]
The version number to test, or, if Null, tests for implementation of the feature in any version. In Level 1, "1.0" is the only valid version value.
hasFeature [out, retval]
True if the specified feature is implemented; otherwise False.

C/C++ Return Values

S_OK
The value returned if successful.

C/C++ Example

IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
VARIANT_BOOL varbFlag ;
BSTR bstrOutput = NULL;
BSTR bstrFeature = ::SysAllocString(_T("MS-DOM"));
HRESULT hr;
IXMLDOMDocument *pIXMLDOMDocument = NULL;

try
{
   // Create an instance of DOMDocument and initialize pIXMLDOMDocument.
   // Load/create an XML fragment.
   hr = pIXMLDOMDocument->get_implementation(&pIXMLDOMImplementation);

   if(SUCCEEDED(hr) && pIXMLDOMImplementation)
   {
      hr = pIXMLDOMImplementation->hasFeature(bstrFeature, _T("1.0"), &varbFlag);
      if(varbFlag == VARIANT_TRUE )
         bstrOutput = ::SysAllocString(_T("Feature Supported"));
      else
         bstrOutput = ::SysAllocString(_T("Feature not Supported"));

      ::MessageBox(NULL, bstrOutput, bstrFeature, MB_OK);
      ::SysFreeString(bstrOutput);
      bstrOutput = NULL;
      ::SysFreeString(bstrFeature);
      bstrFeature = NULL;
      pIXMLDOMImplementation->Release();
   }
}
catch(...)
{
   if(bstrOutput)
      ::SysFreeString(bstrOutput);
   if(bstrFeature)
      ::SysFreeString(bstrFeature);
   if(pIXMLDOMImplementation)
      pIXMLDOMImplementation->Release();
   DisplayErrorToUser();
}
// Release pIXMLDOMDocument when finished using it.

See Also

Applies to: IXMLDOMImplementation


insertBefore Method

Inserts a child node to the left of the specified node or at the end of the list.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNode.insertBefore(newChild, refChild);

Parameters

newChild
An object. The address of the new node to be inserted.
refChild
A variant. The address of the reference node; newChild is inserted to the left of refChild. If Null, newChild is inserted at the end of the child list.

Return Value

Object. On success, returns the child node that was inserted.

Example

The following script example creates a new IXMLDOMNode object and inserts it before the second child of the top-level node.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var newNode;
var currNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
alert(root.xml);
newNode = xmlDoc.createNode(1, "VIDEOS", "");
currNode = root.insertBefore(newNode, root.childNodes.item(1));
alert(root.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNode.insertBefore(newChild, refChild)

Parameters

newChild
An object. The address of the new node to be inserted.
refChild
A variant. The address of the reference node; newChild is inserted to the left of refChild. If Null, newChild is inserted at the end of the child list.

Return Value

An object. On success, returns the child node that was inserted.

Example

The following Visual Basic example creates a new IXMLDOMNode object and inserts it before the second child of the top-level node.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim newNode As IXMLDOMNode
Dim currNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
MsgBox root.xml
Set newNode = xmlDoc.createNode(NODE_ELEMENT, "VIDEOS", "")
Set currNode = root.insertBefore(newNode, root.childNodes.Item(1))
MsgBox root.xml
[C/C++]

C/C++ Syntax

HRESULT insertBefore(
    IXMLDOMNode *newChild,
    VARIANT refChild,
    IXMLDOMNode **outNewChild);

Parameters

newChild [in]
The address of the new node to be inserted.
refChild [in]
The address of the reference node; newChild is inserted to the left of refChild. If Null, newChild is inserted at the end of the child list.
outNewChild [out, retval]
On success, the child node that was inserted. If Null, no object is created.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if newChild is Null.
E_FAIL
The value returned if an error occurs.

Remarks

This operation depends on the value of the nodeType property.

NODE_ATTRIBUTE

This operation depends on the value of the newChild parameter.

NODE_ATTRIBUTE, NODE_CDATA_SECTION, NODE_COMMENT, NODE_DOCUMENT, NODE_DOCUMENT_TYPE, NODE_ELEMENT, NODE_ENTITY, NODE_NOTATION, NODE_PROCESSING_INSTRUCTION | Returns an error. These node types cannot be children of an attribute.
NODE_DOCUMENT_FRAGMENT | Inserts the children of the document fragment (newChild) and returns newChild.
NODE_ENTITY_REFERENCE, NODE_TEXT | Inserts newChild and returns newChild.
NODE_CDATA_SECTION, NODE_COMMENT, NODE_ENTITY, NODE_NOTATION, NODE_PROCESSING_INSTRUCTION, NODE_TEXT | Returns an error. These node types either cannot have children or their children are read-only.

NODE_DOCUMENT

This operation depends on the value of the newChild parameter.

NODE_ATTRIBUTE, NODE_CDATA_SECTION, NODE_DOCUMENT, NODE_ENTITY, NODE_ENTITY_REFERENCE, NODE_NOTATION, NODE_TEXT | Returns an error. These nodes are not valid as children of a document node.
NODE_COMMENT, NODE_PROCESSING_INSTRUCTION | Inserts newChild and returns newChild.
NODE_ELEMENT | Inserts newChild and returns newChild. By definition, an XML document (the Document node) can have only a single child. Therefore, an error is returned if the Document node already has a child.
NODE_DOCUMENT_FRAGMENT | Inserts the children of the document fragment (in newChild) and returns newChild. The insert operations are subject to the rules for child nodes and can fail if the document fragment children represent node types that cannot be inserted.
NODE_DOCUMENT_TYPE | Returns an error. The document type is read-only.

NODE_DOCUMENT_FRAGMENT

This operation depends on the value of the newChild parameter.

NODE_ATTRIBUTE, NODE_DOCUMENT, NODE_DOCUMENT_TYPE | Returns an error. These nodes types are not valid as children of a document fragment.
NODE_CDATA_SECTION, NODE_COMMENT, NODE_ELEMENT, NODE_ENTITY_REFERENCE, NODE_PROCESSING_INSTRUCTION, NODE_TEXT | Inserts newChild and returns newChild.
NODE_DOCUMENT_FRAGMENT | Inserts the children of the document fragment (newChild) and returns newChild.
NODE_ENTITY, NODE_NOTATION | Returns an error. Entities and notations are read-only and cannot be inserted into a document.

NODE_ELEMENT

This operation depends on the value of the newChild parameter.

NODE_CDATA_SECTION, NODE_COMMENT, NODE_ELEMENT, NODE_ENTITY_REFERENCE, NODE_TEXT, NODE_PROCESSING_INSTRUCTION | Inserts newChild and returns newChild.
NODE_ATTRIBUTE, NODE_DOCUMENT, NODE_DOCUMENT_TYPE, NODE_ENTITY, NODE_NOTATION | Returns an error. These node types cannot be children of an element node.
NODE_DOCUMENT_FRAGMENT | Inserts the children of the document fragment (newChild) and returns newChild.
NODE_ENTITY_REFERENCE | Returns an error. Although the child nodes of an entity reference are the expanded entity, the children cannot be modified.

The node supplied in refChild must be a child node of this node or Null. The newChild is inserted before refChild (as the left sibling) in the child list. If refChild is Null, newChild is inserted at the end of the child list. If refChild is not a child of this node, an error is returned.

If newChild is a node of type DOCUMENT_FRAGMENT, all its children are inserted, in the same order, before refChild. If newChild is already in the tree, it is first removed.

These parameters can represent nodes in the same or different documents. When in the same document, the nodes retain their default attributes and data types. When these parameters represent nodes in different documents, the nodes either lose or alter their default attributes, depending on whether this node's document has a document type definition (DTD) or other schema. The Microsoft XML parser (MSXML) attempts to correctly merge the different DTDs.

If the newChild node's DTD or schema differs from the original document, the nodes will be treated with the definitions in the new DTD, including default attributes and data types. If there is no DTD, the nodes keep their data types by picking up an instance definition (attributes lose their data types), and default attributes are lost. Cutting and pasting between documents with two different DTDs can result in an invalid document that may fail to parse after being saved.

When elements are added as children to other elements, they introduce their own namespace scoping. That is, if the element is from a default namespace, the default has scope beginning with the element being added.

If an entity reference is being added as a child to an element or document fragment, the namespace declaration of the entity reference is added to the containing element. In a similar way, if the entity reference is being added to an attribute, the namespace and the prefix of the entity reference are added to the element containing the attribute.

If there is a conflict between prefixes on the containing element and the prefixes being added, the insertBefore operation fails and returns an error. For example, a conflict occurs when a new attribute referring to a different namespace is added to an element with the namespace, as in the following.

xmlns:myns="URN1"

The error can result from the new attribute, where myns refers to a different namespace, "URN2," such as would result from a call to createNode ("attribute","myns:myname","URN2").

myns:myname="myattributevalue"

Namespace conflict errors occur only when setting attributes. Inserted child elements do not cause a namespace conflict.

When adding a document fragment, the containing element adds all namespaces and prefixes from the document fragment. If this causes a conflict with the containing element, insertBefore returns an error.

See Also

createNode Method | nodeType Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


insertData Method

Inserts a string at the specified offset.

[Script]

Script Syntax

oXMLDOMCharacterData.insertData(offset, data);

Parameters

offset
A long integer specifying the offset, in characters, at which to insert the supplied string data.
data
A string containing the data that is to be inserted into the existing string.

Example

The following script example creates an IXMLDOMComment object and uses the insertData method to insert a string into it.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var comment;
xmlDoc.async = false;
xmlDoc.load("books.xml");
comment = xmlDoc.createComment("Hello World!");
comment.insertData(6, "Beautiful ");
alert(comment.xml);
[Visual Basic]

Visual Basic Syntax

oXMLDOMCharacterData.insertData(offset, data)

Parameters

offset
A long integer specifying the offset, in characters, at which to insert the supplied string data.
data
A string containing the data that is to be inserted into the existing string.

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMComment object and uses the insertData method to insert a string into it.

Dim xmlDoc As New Msxml2.DOMDocument
Dim comment As IXMLDOMComment
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set comment = xmlDoc.createComment("Hello World!")
comment.insertData 6, "Beautiful "
MsgBox (comment.xml)
[C/C++]

C/C++ Syntax

HRESULT insertData(
    long offset,
    BSTR data);

Parameters

offset [in]
The offset, in characters, at which to insert the supplied string data.
data [in]
The string data that is to be inserted into the existing string.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value when returning Null.
E_FAIL
The value returned if an error occurs.

Remarks

The length property is updated by this operation.

See Also

length Property

Applies to: IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | IXMLDOMText


item Method (IXMLDOMNamedNodeMap)

Allows random access to individual nodes within the collection.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNamedNodeMap.item(index);

Parameters

index
A long integer. An index of the item within the collection. The first item is zero.

Return Value

An object. Returns IXMLDOMNode. Returns Null if the index is out of range.

Example

The following script example creates an IXMLDOMNodeList object with the document's getElementsByTagName method. It then iterates through the collection, displaying the text value of each item in the list.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var objNodeList;
xmlDoc.async = false;
xmlDoc.load("books.xml");
objNodeList = xmlDoc.getElementsByTagName("author");
for (var i=0; i<objNodeList.length; i++) {
  alert(objNodeList.item(i).text);
}
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNamedNodeMap.item(index)

Parameters

index
A long integer. Index of the item within the collection. The first item is zero.

Return Value

An object. Returns IXMLDOMNode. Returns Null if the index is out of range.

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNodeList object with the document's getElementsByTagName method. It then iterates through the collection, displaying the text value of each item in the list.

Dim xmlDoc As New Msxml2.DOMDocument
Dim objNodeList As IXMLDOMNodeList
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set objNodeList = xmlDoc.getElementsByTagName("author")
For i = 0 To (objNodeList.length - 1)
  MsgBox objNodeList.Item(i).Text
Next
[C/C++]

C/C++ Syntax

HRESULT get_item(
  long index,
  IXMLDOMNode **listItem);

Parameters

index [in]
The index of the item within the collection. The first item is zero.
listItem [out, retval]
The IXMLDOMNode object. Returns Null if the index is out of range.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if listItem is Null.

See Also

IXMLDOMNode

Applies to: IXMLDOMNamedNodeMap | IXMLDOMSelection


item Method (IXMLDOMNodeList)

Allows random access to individual nodes within the collection.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNodeList.item(index);

Parameters

index
A long integer. An index of the item within the collection. The first item is zero.

Return Value

An object. Returns IXMLDOMNode. Returns Null if the index is out of range.

Example

The following script example creates an IXMLDOMNodeList object with the document's getElementsByTagName method. It then iterates through the collection, displaying the text value of each item in the list.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var objNodeList;
xmlDoc.async = false;
xmlDoc.load("books.xml");
objNodeList = xmlDoc.getElementsByTagName("author");
for (var i=0; i<objNodeList.length; i++) {
  alert(objNodeList.item(i).text);
}
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNodeList.item(index)

Parameters

index
A long integer. An index of the item within the collection. The first item is zero.

Return Value

An object. Returns IXMLDOMNode. Returns Null if the index is out of range.

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNodeList object with the document's getElementsByTagName method. It then iterates through the collection, displaying the text value of each item in the list.

Dim xmlDoc As New Msxml2.DOMDocument
Dim objNodeList As IXMLDOMNodeList
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set objNodeList = xmlDoc.getElementsByTagName("author")
For i = 0 To (objNodeList.length - 1)
  MsgBox objNodeList.Item(i).Text
Next
[C/C++]

C/C++ Syntax

HRESULT get_item(
  long index,
  IXMLDOMNode **listItem);

Parameters

index [in]
An index of the item within the collection. The first item is number zero.
listItem [out, retval]
An IXMLDOMNode. Returns Null if the index is out of range.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if listItem is Null.

See Also

IXMLDOMNode

Applies to: IXMLDOMNodeList | IXMLDOMSelection


load Method

Loads an XML document from the specified location.

[Script]

Script Syntax

boolValue = oXMLDOMDocument.load(xmlSource);

Parameters

xmlSource
A string containing a URL that specifies the location of the XML file.

Return Value

Boolean. Returns True if the load succeeded; False if the load failed.

Example

The following script example creates a DOMDocument object and uses the load method to load a local XML file.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
alert(xmlDoc.xml);
[Visual Basic]

Visual Basic Syntax

boolValue = oXMLDOMDocument.load(xmlSource)

Parameters

xmlSource
A string containing a URL that specifies the location of the XML file.

Return Value

Boolean. Returns True if the load succeeded; False if the load failed.

Example

The following Microsoft Visual Basic® example creates a DOMDocument object and uses the load method to load a local XML file.

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.async = False
xmlDoc.Load ("books.xml")
MsgBox xmlDoc.xml
[C/C++]

C/C++ Syntax

HRESULT load(
    VARIANT xmlSource,
    VARIANT_BOOL *isSuccessful);

Parameters

xmlSource [in]
An indicator of the source XML to parse. This may be an URL (String/BSTR), a Request object (in an ASP page), an IStream, SAFEARRAY of bytes (VT_ARRAY|VT_UI1), a DOMDocument object, or any object that supports IStream, ISequentialStream, or IPersistStream. See Remarks.
isSuccessful [out, retval]
True if the load succeeded; False if the load failed.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned if the load fails.
E_INVALIDARG
The value returned if isSuccessful is Null.

Remarks

If the URL cannot be resolved or accessed or does not reference an XML document, this method returns an error and sets the documentElement property of the DOMDocument to Null.

The load method can also take any object that supports IStream and the Microsoft® Internet Information Services (IIS) Request object.

Calling load or loadXML on an existing document immediately discards the content of the document.

If loading an XML document from a resource, the load must be performed asynchronously or the load will fail. For example:

Set objXML = CreateObject("MSXML2.DOMDocument")
ObjXML.async=true
objXML.load "res://msxml.dll/DEFAULTSS.XSL"
WScript.echo objXML.parseError.reason
objXML.save "c:\defaultss.xsl"

Schemas are not applied when loading XML from a string.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

documentElement Property | loadXML Method | XML DOM Persistence

Applies to: DOMDocument


loadXML Method

Loads an XML document using the supplied string.

[Script]

Script Syntax

boolValue = oXMLDOMDocument.loadXML(bstrXML);

Parameters

bstrXML
A string containing the XML string to load into this XML document object. This string can contain an entire XML document or a well-formed fragment.

Return Value

Boolean. Returns True if the XML load succeeded. Returns False and sets the documentElement property of the DOMDocument to Null if the XML load failed.

Example

The following script example creates a DOMDocument object, and then uses its loadXML method to load the specified XML before displaying it.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.loadXML("<customer><first_name>Joe</first_name><last_name>Smith</last_name></customer>");
alert(xmlDoc.xml);
[Visual Basic]

Visual Basic Syntax

boolValue = oXMLDOMDocument.loadXML(bstrXML)

Parameters

bstrXML
A string containing the XML string to load into this XML document object. This string can contain an entire XML document or a well-formed fragment.

Return Value

Boolean. Returns True if the XML load succeeded. Returns False and sets the documentElement property of the DOMDocument to Null if the XML load failed.

Example

The following Microsoft® Visual Basic® example creates a DOMDocument object, and then uses its loadXML method to load the specified XML before displaying it.

Dim xmlDoc As New Msxml2.DOMDocument
xmlDoc.async = False
xmlDoc.loadXML ("<customer><first_name>Joe</first_name><last_name>Smith</last_name></customer>")
MsgBox xmlDoc.xml
[C/C++]

C/C++ Syntax

HRESULT loadXML(
    BSTR bstrXML,
    VARIANT_BOOL * isSuccessful);

Parameters

bstrXML [in]
An XML string to load into this XML document object. This string can contain an entire XML document or a well-formed fragment.
isSuccessful [out, retval]
True if the XML load succeeded. If the XML load failed, this method returns False and sets the documentElement property of the DOMDocument object to Null.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned if the load fails.
E_INVALIDARG
The value returned if isSuccessful is Null.

Remarks

Calling load or loadXML on an existing document immediately discards the content of the document. The loadXML() will work only with UTF-16 or UCS-2 encodings.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

documentElement property | load Method | XML DOM Persistence

Applies to: DOMDocument


matches Method

Checks if the node that is passed is contained in the current collection.

[Script]

Script Syntax

objXMLDOMNode = objXMLDOMSelection.matches(objXMLDOMNode);

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var oSelection, nodeBook, node;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodeBook = xmlDoc.selectSingleNode("//book");
oSelection = xmlDoc.selectNodes("//*");
node = oSelection.matches(nodeBook);
alert(node.xml);
[Visual Basic]

Visual Basic Syntax

objXMLDOMNode = objXMLDOMSelection.matches(objXMLDOMNode)

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim oSelection As IXMLDOMSelection
Dim nodeBook As IXMLDOMNode
Dim node As IXMLDOMNode
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodeBook = xmlDoc.selectSingleNode("//book")
Set oSelection = xmlDoc.selectNodes("//*")
Set node = oSelection.matches(nodeBook)
MsgBox node.xml
[C/C++]

C/C++ Syntax

HRESULT matches(IXMLDOMNode* pNode, IXMLDOMNode** ppNode);

Parameters

pNode [in]
The node that is passed in.
ppNode [out, retval]
The Boolean result.

C/C++ Return Values

S_OK
The value returned if method successful.
E_INVALIDARG
The value returned if pNode=NULL.

An error for cases that are not allowed, as outlined in the Extensible Stylesheet Language (XSL) specification (applied to ID, IDREF, and Ancestor).

Remarks

When matches is called with node A, it returns node B such that if B was set as the context on a query, A is in the result set of the query. If no such B node is found, matches returns Null.

The matches method does not take into account the current context of the query.

See Also

Applies to: IXMLDOMSelection


nextNode Method (IXMLDOMNamedNodeMap)

Returns the next node in the collection.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNamedNodeMap.nextNode();

Return Value

An IXMLDOMNode, which refers to the next node in the collection. Returns Null if there is no next node.

Example

The following script example creates an IXMLDOMNamedNodeMap object and uses its nextNode method to iterate the collection.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var objNamedNodeMap;
var objNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
objNamedNodeMap = xmlDoc.documentElement.childNodes(1).attributes;
for (var i=0; i<objNamedNodeMap.length; i++) {
  objNode = objNamedNodeMap.nextNode();
  alert(objNode.text);
}
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNamedNodeMap.nextNode

Return Value

An IXMLDOMNode, which refers to the next node in the collection. Returns Null if there is no next node.

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNamedNodeMap object and uses its nextNode method to iterate the collection.

Dim xmlDoc As New Msxml2.DOMDocument
Dim objNamedNodeMap As IXMLDOMNamedNodeMap
Dim objNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set objNamedNodeMap = xmlDoc.documentElement.childNodes(1).Attributes
For i = 0 To (objNamedNodeMap.length - 1)
  Set objNode = objNamedNodeMap.nextNode
  MsgBox objNode.Text
Next
[C/C++]

C/C++ Syntax

HRESULT nextNode(
    IXMLDOMNode **nextItem);

Parameters

nextItem [out, retval]
The next node in the collection, or Null if there is no next node.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value when returning Null.
E_INVALIDARG
The value returned if nextItem is Null.

Remarks

The iterator initially points before the first node in the list so that the first call to nextNode returns the first node in the list.

This method returns Null when the current node is the last node or there are no items in the list. When the current node is removed from the list, subsequent calls to nextNode return Null. The iterator must be reset by calling the reset method.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

IXMLDOMNode | reset Method

Applies to: IXMLDOMNamedNodeMap | IXMLDOMNodeList | IXMLDOMSelection


nextNode Method (IXMLDOMNodeList)

Returns the next node in the collection.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNodeList.nextNode();

Return Value

An IXMLDOMNode refers to the next node in the collection. Returns Null if there is no next node.

Example

The following script example creates an IXMLDOMNodeList object and uses its nextNode method to iterate the collection.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var objNodeList;
var objNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
objNodeList = xmlDoc.getElementsByTagName("author");
for (var i=0; i<objNodeList.length; i++) {
  objNode = objNodeList.nextNode();
  alert(objNode.text);
}
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNodeList.nextNode

Return Value

An IXMLDOMNode refers to the next node in the collection. Returns Null if there is no next node.

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNodeList object and uses its nextNode method to iterate the collection.

Dim xmlDoc As New Msxml2.DOMDocument
Dim objNodeList As IXMLDOMNodeList
Dim objNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set objNodeList = xmlDoc.getElementsByTagName("author")
For i = 0 To (objNodeList.length - 1)
  Set objNode = objNodeList.nextNode
  MsgBox objNode.Text
Next
[C/C++]

C/C++ Syntax

HRESULT nextNode(
    IXMLDOMNode **nextItem);

Parameters

nextItem [out, retval]
The next node in the collection, or Null if there is no next node.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned if nextItem is Null.

Remarks

The iterator initially points before the first node in the list so that the first call to nextNode returns the first node in the list.

This method returns Null when the current node is the last node or there are no items in the list. When the current node is removed from the list, subsequent calls to nextNode return Null. The iterator must be reset by calling the reset method.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

IXMLDOMNode | reset Method

Applies to: IXMLDOMNamedNodeMap | IXMLDOMNodeList | IXMLDOMSelection


nodeFromID Method

Returns the node that matches the ID attribute.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMDocument.nodeFromID(idString);

Parameters

idString
The string containing the value of the ID to match.

Return Value

An object. Returns the node that matches the supplied ID. If no nodes match, returns Null.

[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMDocument.nodeFromID(idString)

Parameters

idString
The string containing the value of the ID to match.

Return Value

An object. Returns the node that matches the supplied ID. If no nodes match, returns Null.

[C/C++]

C/C++ Syntax

HRESULT nodeFromID(
    BSTR idString,
    IXMLDOMNode **node);

Parameters

idString [in]
The value of the ID to match.
node [out, retval]
The node that matches the supplied ID. If no nodes match, this method returns Null.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned when there is no node with the given ID.
E_INVALIDARG
The value returned if node is Null.

Remarks

According to the XML 1.0 Recommendation (REC-xml-19980210), ID attribute values must be unique within their XML documents and no element can specify more than one ID attribute.

The nodeFromID method was designed to handle ID and IDREF relationships in XML, but does not require an attribute of type IDREF. It can be used generically, and is similar to the all collection in DHTML.

To reference a node with nodefromID, the node must be typed as ID in the schema or document type definition (DTD). Simply naming an attribute "ID" does not set its data type.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

Applies to: DOMDocument


normalize Method

Normalizes all descendant elements by combining two or more adjacent text nodes into one unified text node.

[Script]

Script Syntax

oXMLDOMElement.normalize();

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeRoot;
xmlDoc.async = false;
xmlDoc.loadXML("<root/>");
nodeRoot = xmlDoc.documentElement;
nodeRoot.appendChild(xmlDoc.createTextNode("Hello "));
nodeRoot.appendChild(xmlDoc.createTextNode("World"));
nodeRoot.appendChild(xmlDoc.createTextNode("!"));
alert(nodeRoot.childNodes.length);
nodeRoot.normalize();
alert(nodeRoot.childNodes.length);
[Visual Basic]

Visual Basic Syntax

oXMLDOMElement.normalize

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeRoot As IXMLDOMElement
xmlDoc.async = False
xmlDoc.loadXML "<root/>"
Set nodeRoot = xmlDoc.documentElement
nodeRoot.appendChild xmlDoc.createTextNode("Hello ")
nodeRoot.appendChild xmlDoc.createTextNode("World")
nodeRoot.appendChild xmlDoc.createTextNode("!")
MsgBox nodeRoot.childNodes.length
nodeRoot.normalize
MsgBox nodeRoot.childNodes.length
[C/C++]

C/C++ Syntax

HRESULT normalize(void);

C/C++ Return Values

S_OK
The value returned if successful.
E_FAIL
The value returned if an error occurs.

C/C++ Example

BOOL DOMElementNormalize()
{
   BOOL bResult = FALSE;
   IXMLDOMElement *pIXMLDOMElement = NULL;
   IXMLDOMDocument *pIXMLDOMDocument = NULL;
   HRESULT hr;

   try
   {
      // Create an instance of DOMDocument and initialize
      // pIXMLDOMDocument.
      // Load/create an XML fragment.
      hr = pIXMLDOMDocument->get_documentElement(&pIXMLDOMElement);
      SUCCEEDED(hr) ? 0 : throw hr;

      if(pIXMLDOMElement )
      {
         hr = pIXMLDOMElement->normalize();
         if(SUCCEEDED(m_hr))
            bResult = TRUE;
         pIXMLDOMElement->Release();
      }
   }
   catch(...)
   {
      if(pIXMLDOMElement)
         pIXMLDOMElement->Release();
      DisplayErrorToUser();
   }
   return bResult;
}

Remarks

This method converts all text node descendants of this element (at any depth) into a "normal" form where no text nodes are adjacent. In normal form, text nodes can be separated only by markup, such as tags, comments, processing instructions, CDATA sections, and entity references. The normal form is useful for operations that require a particular document tree structure and ensures that the XML Document Object Model (DOM) view of a document is identical when saved and reloaded.

Collapsed node objects are deleted automatically.

See Also

IXMLDOMText

Applies to: IXMLDOMElement


open Method (IXMLHTTPRequest)

Initializes an MSXML2.XMLHTTP request and specifies the method, URL, and authentication information for the request.

[Script]

Script Syntax

oXMLHttpRequest.open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword);

Parameters

bstrMethod
A string. HTTP method used to open the connection, such as GET, POST, PUT, or PROPFIND.
bstrUrl
A string. Requested URL. This must be an absolute URL, such as "http://Myserver/Mypath/Myfile.asp".
varAsync [optional]
Boolean. Indicator of whether the call is asynchronous. The default is True (the call returns immediately). If set to True, attach an onreadystatechange property callback so that you can tell when the send call has completed.
bstrUser [optional]
The name of the user for authentication. If this parameter is Null ("") or missing and the site requires authentication, the component displays a logon window.
bstrPassword [optional]
The password for authentication. This parameter is ignored if the user parameter is Null ("") or missing.

Example

The following script example creates an XMLHTTP object, and then uses the open method to synchronously open an Active Server Pages (ASP) page. It then posts an XML document to an ASP page, which uses the load method to load it.

var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlHTTP.open("GET","http://myserver/save.asp", false);
xmlHTTP.send(xmlDoc)

The following code belongs on the server.

<% xmlDoc.load(Request); %>
[Visual Basic]

Visual Basic Syntax

oXMLHttpRequest.open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword)

Parameters

bstrMethod
A string. HTTP method used to open the connection, such as GET, POST, PUT, or PROPFIND.
bstrUrl
A string. Requested URL. This must be an absolute URL, such as "http://Myserver/Mypath/Myfile.asp".
varAsync [optional]
Boolean. Indicator of whether the call is asynchronous. The default is True (the call returns immediately). If set to True, attach an onreadystatechange property callback so that you can tell when the send call has completed.
bstrUser [optional]
The name of the user for authentication. If this parameter is Null ("") or missing and the site requires authentication, the component displays a logon window.
bstrPassword [optional]
The password for authentication. This parameter is ignored if the user parameter is Null ("") or missing.
[C/C++]

C/C++ Syntax

HRESULT open(BSTR bstrMethod, BSTR bstrUrl, VARIANT varAsync,
 VARIANT bstrUser, VARIANT bstrPassword);

Parameters

bstrMethod [in]
The HTTP method used to open the connection, such as PUT or PROPFIND.
bstrUrl [in]
The requested URL. This must be an absolute URL, such as "http://Myserver/Mypath/Myfile.asp".
varAsync [in, optional]
Boolean. Indicator as to whether the call is asynchronous. The default is True (the call returns immediately). If set to True, attach an onreadystatechange property callback so that you can tell when the send call has completed.
bstrUser [in, optional]
The name of the user for authentication. If this parameter is Null ("") or missing and the site requires authentication, the component displays a logon window.
bstrPassword [in, optional]
The password for authentication. This parameter is ignored if the user parameter is Null or missing.

C/C++ Return Values

S_OK
The value returned if successful.

C/C++ Example

HRESULT hr;
IXMLHttpRequest *pIXMLHttpRequest = NULL;

try
{
   // Create XMLHttpRequest object and initialize pIXMLHttpRequest.
   hr = pIXMLHttpRequest->open(_bstr_t(_T("PUT")),
      _bstr_t(_T("GET","http://MyServer/Sample.xml", false)),
      _variant_t(VARIANT_FALSE), _variant_t(""), _variant_t(""));
   if(SUCCEEDED(hr))
      ::MessageBox(NULL, _T("Success !"), _T(""), MB_OK);
}
catch(...)
{
   DisplayErrorToUser();
}
// Release pIXMLHttpRequest when finished with it.

Remarks

The values of the request headers, request body, response headers, and response body must be cleared before calling this method.

After calling this method, you must call send to send the request and data, if any, to the server.

See Also

abort Method | onreadystatechange Property

Applies to: IXMLHTTPRequest


open Method (ServerXMLHTTP/IServerXMLHTTPRequest)

Initializes a request and specifies the method, URL, and authentication information for the request.

[Script]

Script Syntax

oServerXMLHTTPRequest.open(bstrMethod, bstrUrl, bAsync, bstrUser,
bstrPassword);

Parameters

bstrMethod
The HTTP method used to open the connection, such as PUT or PROPFIND.
bstrUrl
The requested URL. This must be an absolute URL, such as "http://Myserver/Mypath/Myfile.asp".
bAsync (optional)
Boolean. Indicator as to whether the call is asynchronous. The default is False (the call does not return immediately).
bstrUser (optional)
The name of the user for authentication.
bstrPassword (optional)
The password for authentication. This parameter is ignored if the user parameter is Null or missing.

Example

<%@language=JScript%>
<%
var srvXmlHttp
srvXmlHttp = Server.CreateObject("Msxml2.ServerXMLHTTP");
srvXmlHttp.open ("GET", "http://myserver/myresponse.asp", false);
srvXmlHttp.send();
newsElement = srvXmlHttp.responseXML.selectSingleNode("/news/story1");
%>

<html>
<body>
<p>Top News Story<p>
<%Response.write(newsElement.text);%>
</body>
</html>
[Visual Basic]

Visual Basic Syntax

oServerXMLHTTPRequest.open(bstrMethod, bstrUrl, bAsync, bstrUser,
 bstrPassword)

Parameters

bstrMethod
The HTTP method used to open the connection, such as PUT or PROPFIND.
bstrUrl
The requested URL. This must be an absolute URL, such as "http://Myserver/Mypath/Myfile.asp".
bAsync (optional)
Boolean. Indicator as to whether the call is asynchronous. The default is False (the call does not return immediately).
bstrUser (optional)
The name of the user for authentication. If this parameter is Null ("") or missing and the site requires authentication, the component displays a logon window.
bstrPassword (optional)
The password for authentication. This parameter is ignored if the user parameter is Null or missing.
[C/C++]

C/C++ Syntax

HRESULT open(BSTR bstrMethod, BSTR bstrUrl, VARIANT bAsync,
VARIANT bstrUser, VARIANT bstrPassword);

Parameters

bstrMethod [in]
The HTTP method used to open the connection, such as PUT or PROPFIND.
bstrUrl [in]
The requested URL. This must be an absolute URL, such as "http://Myserver/Mypath/Myfile.asp".
bAsync [in, optional]
Boolean. Indicator as to whether the call is asynchronous. The default is False (the call does not return immediately).
bstrUser [in, optional]
The name of the user for authentication. If this parameter is Null ("") or missing and the site requires authentication, the component displays a logon window.
bstrPassword [in, optional]
The password for authentication. This parameter is ignored if the user parameter is Null or missing.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

The values of the request headers, request body, response headers, and response body must be cleared before calling this method.

After calling this method you must call send to send the request and data (if any) to the server. Each send method must have a corresponding open method.

See Also

abort Method

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


peekNode Method

Gets the next node that nextNode will return without advancing the list position.

[Script]

Script Syntax

var objXMLDOMNode = objXMLDOMSelection.peekNode();

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var oSelection, nodeBook;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.async = false;
xmlDoc.load("books.xml");
oSelection = xmlDoc.selectNodes("//book");
nodeBook = oSelection.peekNode();
alert(nodeBook.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = objXMLDOMSelection.peekNode

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim oSelection As IXMLDOMSelection
Dim nodeBook As IXMLDOMElement
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set oSelection = xmlDoc.selectNodes("//book")
Set nodeBook = oSelection.peekNode()
MsgBox nodeBook.xml
[C/C++]

C/C++ Syntax

HRESULT peekNode (IXMLDOMNode** ppNode);

Parameters

ppNode [out, retval]
The returned node, or Null if there are no more nodes or if E_PENDING is returned.

C/C++ Return Values

S_OK
The value returned if the method is successful.
E_PENDING
The value returned if the context document is still being built and the selection object has hit the end of the available nodes to match.

Remarks

Like nextNode, peekNode does not result in a snapshot of all matching nodes. Consecutive calls to peekNode will produce the same node over and over, independent of changes in the underlying tree.

See Also

Applies to: IXMLDOMSelection


remove Method

Removes the specified namespace from a collection.

[Script]

Script Syntax

objXMLDOMSchemaCol.remove(namespaceURI);

Parameters

namespaceURI
The namespace to remove from the collection. This can be any string that can be used in an xmlns attribute, but it cannot contain entity references. The same white space normalization that occurs on the xmlns attribute occurs on this argument (that is, leading and trailing white space is trimmed, new lines are converted to spaces, and multiple adjacent white space characters are collapsed into one space).
[Visual Basic]

Visual Basic Syntax

objXMLDOMSchemaCol.remove(namespaceURI)

Parameters

namespaceURI
The namespace to remove from the collection. This can be any string that can be used in an xmlns attribute, but it cannot contain entity references. The same white space normalization that occurs on the xmlns attribute occurs on this argument (that is, leading and trailing white space is trimmed, new lines are converted to spaces, and multiple adjacent white space characters are collapsed into one space).
[C/C++]

C/C++ Syntax

HRESULT remove(BSTR namespaceURI);

Parameters

namespaceURI [in]
The namespace to remove from the collection.

This can be any string that can be used in an xmlns attribute, but it cannot contain entity references. The same white space normalization that occurs on the xmlns attribute occurs on this argument (that is, leading and trailing white space is trimmed, new lines are converted to spaces, and multiple adjacent white space characters are collapsed into one space).

C/++Return Values

E_INVALIDARG
The value returned if the namespace does not exist in the collection.
E_FAIL
The value returned if the collection is read-only.

See Also

Applies to: IXMLDOMSchemaCollection/XMLSchemaCache


removeAll Method

Removes all the nodes from the collection described by the IXMLDOMSelection.

[Script]

Script Syntax

objXMLDOMSelection.removeAll();

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var oSelection;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.async = false;
xmlDoc.load("books.xml");
alert(xmlDoc.xml);
oSelection = xmlDoc.selectNodes("//book");
oSelection.removeAll();
alert(xmlDoc.xml);
[Visual Basic]

Visual Basic Syntax

objXMLDOMSelection.removeAll

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim oSelection As IXMLDOMSelection
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.async = False
xmlDoc.Load "books.xml"
MsgBox xmlDoc.xml
Set oSelection = xmlDoc.selectNodes("//book")
oSelection.removeAll
MsgBox xmlDoc.xml
[C/C++]

C/C++ Syntax

HRESULT removeAll();

C/C++ Return Values

S_OK
The value returned if the method is successful.
E_PENDING
The value returned if all nodes cannot be found at this time (in which case no nodes are removed).

See Also

Applies to: IXMLDOMSelection


removeAttribute Method

Removes or replaces the named attribute.

[Script]

Script Syntax

oXMLDOMElement.removeAttribute(name);

Parameters

name
A string specifying the name of the attribute to be removed or replaced.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeBook;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodeBook = xmlDoc.selectSingleNode("//book");
alert(nodeBook.attributes.length);
nodeBook.removeAttribute("id");
alert(nodeBook.attributes.length);
[Visual Basic]

Visual Basic Syntax

oXMLDOMElement.removeAttribute(name)

Parameters

name
A string specifying the name of the attribute to be removed or replaced.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeBook As IXMLDOMElement
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodeBook = xmlDoc.selectSingleNode("//book")
MsgBox nodeBook.Attributes.length
nodeBook.removeAttribute "id"
MsgBox nodeBook.Attributes.length
[C/C++]

C/C++ Syntax

HRESULT removeAttribute(
    BSTR name);

Parameters

name [in]
The name of the attribute to be removed or replaced.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned when no attribute with the given name is found.
E_FAIL
The value returned if an error occurs.

C/C++ Example

IXMLDOMElement *pIXMLDOMElement = NULL;
_bstr_t bstrAttributeName = _T("dateCreated");
IXMLDOMDocument *pIXMLDOMDocument = NULL;
HRESULT hr;

try
{
   // Create an instance of DOMDocument and initialize pIXMLDOMDocument.
   // Load/create an XML fragment.
   hr = pIXMLDOMDocument->get_documentElement(&pIXMLDOMElement);
   SUCCEEDED(hr) ? 0 : throw hr;

   hr = pIXMLDOMElement->removeAttribute(bstrAttributeName);
   if(SUCCEEDED(hr))
   {
   // Attribute removed.
   }
   pIXMLDOMElement->Release();
   pIXMLDOMElement = NULL;
   // Release pIXMLDOMDocument when finished with it.
}
catch(...)
{
   // Release pIXMLDOMDocument if it exists.
   if(pIXMLDOMElement)
      pIXMLDOMElement->Release();
   DisplayErrorToUser();
}

Remarks

If the specified attribute has a default value, this is equivalent to a replace operation: The current value is removed and a new attribute is created with the default value. This operation also resets the specified property of IXMLDOMNode.

See Also

specified Property

Applies to: IXMLDOMElement


removeAttributeNode Method

Removes the specified attribute from this element.

[Script]

Script Syntax

var objXMLDOMAttribute = oXMLDOMElement.removeAttributeNode(DOMAttribute);

Parameters

DOMAttribute
An object that supplies the IXMLDOMAttribute object to be removed from this element.

Return Value

An object. Returns the removed element.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeBook, nodeId;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodeBook = xmlDoc.selectSingleNode("//book");
nodeId = nodeBook.getAttributeNode("id");
alert(nodeBook.attributes.length);
nodeBook.removeAttributeNode(nodeId);
alert(nodeBook.attributes.length);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMAttribute = oXMLDOMElement.removeAttributeNode(DOMAttribute)

Parameters

DOMAttribute
An object that supplies the IXMLDOMAttribute object to be removed from this element.

Return Value

An object. Returns the removed element.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeBook As IXMLDOMElement
Dim nodeId As IXMLDOMAttribute
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodeBook = xmlDoc.selectSingleNode("//book")
Set nodeId = nodeBook.getAttributeNode("id")
MsgBox nodeBook.Attributes.length
nodeBook.removeAttributeNode nodeId
MsgBox nodeBook.Attributes.length
[C/C++]

C/C++ Syntax

HRESULT removeAttributeNode(
    IXMLDOMAttribute *DOMAttribute,
    IXMLDOMAttribute **attributeNode);

Parameters

DOMAttribute [in]
The DOMAttribute object that is to be removed from this element.
attributeNode [out, retval]
The removed element.

C/C++ Return Values

S_OK
The value returned if successful.
E_FAIL
The value returned if an error occurs.

C/C++ Example

IXMLDOMElement *pIXMLDOMElement = NULL;
_bstr_t bstrAttributeName = _T("dateCreated");
IXMLDOMAttribute *pIXMLDOMAttribute = NULL;
IXMLDOMAttribute *pRemovedIXMLDOMAttribute = NULL;
IXMLDOMDocument *pIXMLDOMDocument = NULL;
HRESULT hr;

try
{
// Create an instance of DOMDocument and initialize pIXMLDOMDocument.
// Load/create an XML fragment.
hr = pIXMLDOMDocument->get_documentElement(&pIXMLDOMElement);
SUCCEEDED(hr) ? 0 : throw hr;

if(pIXMLDOMElement)
{
hr = pIXMLDOMElement->getAttributeNode(bstrAttributeName, &pIXMLDOMAttribute);
if(SUCCEEDED(hr) && pIXMLDOMAttribute)
{
hr = pIXMLDOMElement->removeAttributeNode(pIXMLDOMAttribute, &pRemovedIXMLDOMAttribute);
if(SUCCEEDED(hr))
// Attribute node removed.
bResult = TRUE;
pIXMLDOMAttribute->Release();
}
pIXMLDOMElement->Release();
}
// Release pIXMLDOMDocument when finished with it.
}
catch(...)
{
// Release pIXMLDOMDocument if it exists.
if(pIXMLDOMAttribute)
pIXMLDOMAttribute->Release();
if(pIXMLDOMElement)
pIXMLDOMElement->Release();
DisplayErrorToUser();
}

Remarks

If the attribute has a default value, this call also creates a new attribute with the default value, associates the new attribute with this element, and resets the attribute's specified property.

See Also

specified Property | IXMLDOMAttribute

Applies to: IXMLDOMElement


removeChild Method

Removes the specified child node from the list of children and returns it.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNode.removeChild(childNode);

Parameters

childNode
An object. Child node to be removed from the list of children of this node.

Return Value

An object. Returns the removed child node.

Example

The following script example creates an IXMLDOMNode object (currNode), removes a child node from it, and displays the text of the removed node.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var currNode;
var oldChild;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
currNode = root.childNodes.item(1);
oldChild = currNode.removeChild(currNode.childNodes.item(1));
alert(oldChild.text);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNode.removeChild(childNode)

Parameters

childNode
An object. The child node to be removed from the list of children of this node.

Return Value

An object. Returns the removed child node.

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNode object (currNode), removes a child node from it, and displays the text of the removed node.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim currNode As IXMLDOMNode
Dim oldChild As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
Set currNode = root.childNodes.Item(1)
Set oldChild = currNode.removeChild(currNode.childNodes.Item(1))
MsgBox oldChild.Text
[C/C++]

C/C++ Syntax

HRESULT removeChild(
    IXMLDOMNode *childNode,
    IXMLDOMNode **outOldChild);

Parameters

childNode [in]
The child node to be removed from the list of children of this node.
outOldChild [out, retval]
The removed child node. If Null, no object is created.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if oldChild is not a child of this node, when the specified oldChild is read-only and cannot be removed, or when oldChild is Null.
E_FAIL
The value returned if an error occurs.

See Also

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


removeNamedItem Method

Removes an attribute from the collection.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNamedNodeMap.removeNamedItem(name);

Parameters

name
The string specifying the name of the attribute to remove from the collection.

Return Value

An object. Returns the node removed from the collection. Returns Null if the named node is not an attribute.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeBook;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodeBook = xmlDoc.selectSingleNode("//book");
alert(nodeBook.attributes.length);
nodeBook.attributes.removeNamedItem("id");
alert(nodeBook.attributes.length);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNamedNodeMap.removeNamedItem(name)

Parameters

name
A string specifying the name of the attribute to remove from the collection.

Return Value

An object. Returns the node removed from the collection. Returns Null if the named node is not an attribute.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeBook As IXMLDOMElement
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodeBook = xmlDoc.selectSingleNode("//book")
MsgBox nodeBook.Attributes.length
nodeBook.Attributes.removeNamedItem "id"
MsgBox nodeBook.Attributes.length
[C/C++]

C/C++ Syntax

HRESULT removeNamedItem(
    BSTR name,
    IXMLDOMNode **namedItem);

Parameters

name [in]
The name of the attribute to remove from the collection.
namedItem [out, retval]
The node removed from the collection. Returns Null if the named node is not an attribute.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value when returning Null.
E_FAIL
The value returned if an error occurs.

C/C++ Example

IXMLDOMNode *pIXMLDOMNode = NULL;
IXMLDOMNamedNodeMap *pIXMLDOMNamedNodeMap = NULL;
BSTR bstrAttributeName = ::SysAllocString(_T("dateModified"));
IXMLDOMElement *pIXMLDOMElement = NULL;
VARIANT varValue;
HRESULT hr;
IXMLDOMDocument *pIXMLDOMDocument = NULL;

try
{
// Create an instance of DOMDocument and initialize pIXMLDOMDocument.
// Load/create an XML fragment.
hr = pIXMLDOMDocument->get_documentElement(&pIXMLDOMElement);
SUCCEEDED(hr) ? 0 : throw hr;

if(pIXMLDOMElement)
{
hr = pIXMLDOMElement->get_attributes(&pIXMLDOMNamedNodeMap);
if(SUCCEEDED(hr) && pIXMLDOMNamedNodeMap)
{
hr = pIXMLDOMNamedNodeMap->removeNamedItem(bstrAttributeName, &pIXMLDOMNode);
if(SUCCEEDED(hr) && pIXMLDOMNode)
{
pIXMLDOMNode->get_nodeValue(&varValue);
::MessageBox(NULL, _bstr_t(varValue), _T("Removed Item"), MB_OK);
pIXMLDOMNode->Release();
pIXMLDOMNode = NULL;
}
pIXMLDOMNamedNodeMap->Release();
pIXMLDOMNamedNodeMap = NULL;
}
pIXMLDOMElement->Release();
pIXMLDOMElement = NULL;
}
::SysFreeString(bstrAttributeName);
bstrAttributeName = NULL;
}
catch(...)
{
if(bstrAttributeName)
::SysFreeString(bstrAttributeName);
if(pIXMLDOMElement)
pIXMLDOMElement->Release();
if(pIXMLDOMNamedNodeMap)
pIXMLDOMNamedNodeMap->Release();
if(pIXMLDOMNode)
pIXMLDOMNode->Release();
DisplayErrorToUser();
}
// Release pIXMLDOMDocument when finished with it.

See Also

Applies to: IXMLDOMNamedNodeMap


removeNext Method

Removes the next node.

[Script]

Script Syntax

var objXMLDOMNode = objXMLDOMSelection.removeNext();

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var oSelection;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.async = false;
xmlDoc.load("books.xml");
oSelection = xmlDoc.selectNodes("//book");
while (oSelection.peekNode() != null) {
    oSelection.removeNext();
}
alert(xmlDoc.xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = objXMLDOMSelection.removeNext

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim oSelection As IXMLDOMSelection
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set oSelection = xmlDoc.selectNodes("//book")
While Not (oSelection.peekNode() Is Nothing)
    oSelection.removeNext
Wend
MsgBox xmlDoc.xml
[C/C++]

C/C++ Syntax

HRESULT removeNext(IXMLDOMNode ** ppNode);

Parameters

ppNode [out, retval]
The node that was removed, or Null if there is no nextNode to remove. If the parameter is Null, the removed node is not returned, but is still removed.

C/C++ Return Values

S_OK
The value returned if the method is successful.
S_FALSE
The value returned if no nodes left in the selection.
E_PENDING
The value returned if all nodes cannot be found at this time (in which case no nodes are removed).

Remarks

The removeNext method is equivalent to the following (except that it also works for attributes).

var node = list.peekNode();
node.parentNode.removeChild(node);

The side effect is that the length of the collection is decremented and the nextNode and item methods will not return it because it has been removed.

See Also

Applies to: IXMLDOMSelection


removeQualifiedItem Method

Removes the attribute with the specified namespace and attribute name.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNamedNodeMap.removeQualifiedItem(baseName,
    namespaceURI);

Parameters

baseName
The string specifying the base name of the attribute, without namespace qualification.
namespaceURI
The string specifying the namespace prefix that qualifies the attribute name.

Return Value

An object. Returns the attribute node removed, or Null if no node was removed.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeBook;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodeBook = xmlDoc.selectSingleNode("//book");
alert(nodeBook.attributes.length);
nodeBook.attributes.removeQualifiedItem("id", "");
alert(nodeBook.attributes.length);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNamedNodeMap.removeQualifiedItem(baseName,
    namespaceURI)

Parameters

baseName
The string specifying the base name of the attribute, without namespace qualification.
namespaceURI
The string specifying the namespace prefix that qualifies the attribute name.

Return Value

An object. Returns the attribute node removed, or Null if no node was removed.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeBook As IXMLDOMElement
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodeBook = xmlDoc.selectSingleNode("//book")
MsgBox nodeBook.Attributes.length
nodeBook.Attributes.removeQualifiedItem "id", ""
MsgBox nodeBook.Attributes.length
[C/C++]

C/C++ Syntax

HRESULT removeQualifiedItem(
    BSTR baseName,
    BSTR namespaceURI,
    IXMLDOMNode **qualifiedItem);

Parameters

baseName [in]
The base name of the attribute, without namespace qualification.
namespaceURI [in]
The namespace prefix that qualifies the attribute name.
qualifiedItem [out, retval]
The attribute node removed, or Null if no node was removed.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value when returning Null.
E_FAIL
The value returned if an error occurs.

C/C++ Example

IXMLDOMNode *pIXMLDOMNode = NULL;
IXMLDOMNamedNodeMap *pIXMLDOMNamedNodeMap = NULL;
BSTR bstrAttributeName = ::SysAllocString(_T("dateModified"));
IXMLDOMElement *pIXMLDOMElement = NULL;
VARIANT varValue;
HRESULT hr;
IXMLDOMDocument *pIXMLDOMDocument = NULL;

try
{
// Create an instance of DOMDocument and initialize pIXMLDOMDocument.
// Load/create an XML fragment.
hr = pIXMLDOMDocument->get_documentElement(&pIXMLDOMElement);
SUCCEEDED(hr) ? 0 : throw hr;

if(pIXMLDOMElement)
{
hr = pIXMLDOMElement->get_attributes(&pIXMLDOMNamedNodeMap);
if(SUCCEEDED(hr) && pIXMLDOMNamedNodeMap)
{
hr = pIXMLDOMNamedNodeMap->removeQualifiedItem(bstrAttributeName, NULL,
 &pIXMLDOMNode);
if(SUCCEEDED(hr) && pIXMLDOMNode)
{
pIXMLDOMNode->get_nodeValue(&varValue);
::MessageBox(NULL, _bstr_t(varValue), _T("Removed Item"), MB_OK);
pIXMLDOMNode->Release();
pIXMLDOMNode = NULL;
}
pIXMLDOMNamedNodeMap->Release();
pIXMLDOMNamedNodeMap = NULL;
}
pIXMLDOMElement->Release();
pIXMLDOMElement = NULL;
}
::SysFreeString(bstrAttributeName);
bstrAttributeName = NULL;
}
catch(...)
{
if(bstrAttributeName)
::SysFreeString(bstrAttributeName);
if(pIXMLDOMElement)
pIXMLDOMElement->Release();
if(pIXMLDOMNamedNodeMap)
pIXMLDOMNamedNodeMap->Release();
if(pIXMLDOMNode)
pIXMLDOMNode->Release();
DisplayErrorToUser();
}
// Release pIXMLDOMDocument when finished with it.

Remarks

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

Applies to: IXMLDOMNamedNodeMap


replaceChild Method

Replaces the specified old child node with the supplied new child node.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNode.replaceChild(newChild, oldChild);

Parameters

newChild
An object. The address of the new child that is to replace the old child. If Null, oldChild is removed without a replacement.
oldChild
An object. The address of the old child that is to be replaced by the new child.

Return Value

An object. Returns the old child that is replaced.

Example

The following example creates a new IXMLDOMNode object, newElem, and replaces the specified child node with newElem.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var root;
var newElem;
xmlDoc.async = false;
xmlDoc.load("books.xml");
root = xmlDoc.documentElement;
newElem = xmlDoc.createElement("PAGES");
root.childNodes.item(1).replaceChild(newElem, root.childNodes.item(1).childNodes.item(0));
alert(root.childNodes.item(1).xml);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNode.replaceChild(newChild, oldChild)

Parameters

newChild
An object. The address of the new child that is to replace the old child. If Null, oldChild is removed without a replacement.
oldChild
An object. The address of the old child that is to be replaced by the new child.

Return Value

An object. Returns the old child that is replaced.

Example

The following Microsoft® Visual Basic® example creates a new IXMLDOMNode object, newElem, and replaces the specified child node with newElem.

Dim xmlDoc As New Msxml2.DOMDocument
Dim root As IXMLDOMElement
Dim newElem As IXMLDOMElement
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set root = xmlDoc.documentElement
Set newElem = xmlDoc.createElement("PAGES")
root.childNodes.Item(1).replaceChild newElem, root.childNodes.Item(1).childNodes.Item(0)
MsgBox root.childNodes.Item(1).xml
[C/C++]

C/C++ Syntax

HRESULT replaceChild(
    IXMLDOMNode *newChild,
    IXMLDOMNode *oldChild,
    IXMLDOMNode **outOldChild);

Parameters

newChild [in]
The address of the new child that is to replace the old child. If Null, oldChild is removed without a replacement.
oldChild [in]
The address of the old child that is to be replaced by the new child.
outOldChild [out, retval]
The old child that is replaced. If Null, no object is created.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if the newChild node cannot be inserted as a child of this node, when the specified oldChild is not a child of this node, or if oldChild is Null.
E_FAIL
The value returned if an error occurs.

Remarks

This operation depends on the value of the nodeType property.

NODE_ATTRIBUTE

This operation depends on the value of the newChild parameter:

NODE_ATTRIBUTE, NODE_CDATA_SECTION, NODE_COMMENT, NODE_DOCUMENT, NODE_DOCUMENT_TYPE, NODE_ELEMENT, NODE_ENTITY, NODE_NOTATION, NODE_PROCESSING_INSTRUCTION | Returns an error. These node types cannot be children of an attribute.
NODE_DOCUMENT_FRAGMENT | Replaces oldChild with the children of the document fragment in newChild and returns oldChild.
NODE_ENTITY_REFERENCE, NODE_TEXT | Replaces the specified oldChild with the supplied newChild and returns oldChild.
NODE_CDATA_SECTION, NODE_COMMENT, NODE_ENTITY, NODE_NOTATION, NODE_PROCESSING_INSTRUCTION, NODE_TEXT | Returns an error. These node types either cannot have children or their children are read-only.

NODE_DOCUMENT

This operation depends on the value of the newChild parameter.

NODE_ATTRIBUTE, NODE_CDATA_SECTION, NODE_DOCUMENT, NODE_ENTITY, NODE_ENTITY_REFERENCE, NODE_NOTATION, NODE_TEXT | Returns an error. These nodes are not valid as children of a document node.
NODE_COMMENT, NODE_PROCESSING_INSTRUCTION | Replaces the specified oldChild with the supplied newChild and returns oldChild.
NODE_DOCUMENT_TYPE, NODE_ELEMENT | Replaces oldChild with newChild and returns oldChild. By definition, an XML document (the document node) can have only a single child. Therefore, an error is returned if the document node already has a child.
NODE_DOCUMENT_FRAGMENT | Replaces the specified oldChild with the children of the document fragment (newChild) and returns oldChild. The insert operations are subject to the rules for child nodes and can fail if the document fragment children represent node types that cannot be inserted.
NODE_DOCUMENT_TYPE | Returns an error. The document type is read-only.

NODE_DOCUMENT_FRAGMENT

This operation depends on the value of the newChild parameter.

NODE_ATTRIBUTE, NODE_DOCUMENT, NODE_DOCUMENT_TYPE | Returns an error. These nodes types are not valid as children of a document fragment.
NODE_CDATA_SECTION, NODE_COMMENT, NODE_ELEMENT, NODE_ENTITY_REFERENCE, NODE_PROCESSING_INSTRUCTION, NODE_TEXT | Replaces the specified oldChild with the supplied newChild and returns oldChild.
NODE_DOCUMENT_FRAGMENT | Replaces the specified oldChild with the children of the document fragment (newChild) and returns oldChild. The insert operations are subject to the rules for child nodes and can fail if the document fragment children represent node types that cannot be inserted.
NODE_ENTITY, NODE_NOTATION | Returns an error. Entities and notations are read-only and cannot be inserted into a document.

NODE_ELEMENT

This operation depends on the value of the newChild parameter.

NODE_CDATA_SECTION, NODE_COMMENT, NODE_ELEMENT, NODE_ENTITY_REFERENCE, NODE_TEXT, NODE_PROCESSING_INSTRUCTION | Replaces the specified oldChild with newChild and returns oldChild.
NODE_ATTRIBUTE, NODE_DOCUMENT, NODE_DOCUMENT_TYPE, NODE_ENTITY, NODE_NOTATION | Returns an error. These node types cannot be children of an element node.
NODE_DOCUMENT_FRAGMENT | Replaces the specified oldChild with the children of the document fragment (newChild) and returns oldChild. The insert operations are subject to the rules for child nodes and can fail if the document fragment children represent node types that cannot be inserted.
NODE_ENTITY_REFERENCE | Returns an error. Although the child nodes of an entity reference are the expanded entity, the children cannot be modified.

See Also

nodeType Property

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


replaceData Method

Replaces the specified number of characters with the supplied string.

[Script]

Script Syntax

oXMLDOMCharacterData.replaceData(offset, count, data);

Parameters

offset
The long integer value specifying the offset, in characters, at which to start replacing string data.
count
The long integer value specifying the number of characters to replace.
data
The string containing the new data that replaces the old string data.

Example

The following script example creates a new IXMLDOMComment object, and then replaces the first five characters with a new string.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var comment;
xmlDoc.async = false;
xmlDoc.load("books.xml");
comment = xmlDoc.createComment("Hello World!");
alert(comment.xml);
comment.replaceData(0, 5, "Goodbye, Cruel");
alert(comment.xml);
[Visual Basic]

Visual Basic Syntax

oXMLDOMCharacterData.replaceData(offset, count, data)

Parameters

offset
The long integer value specifying the offset, in characters, at which to start replacing string data.
count
The long integer value specifying the number of characters to replace.
data
The string containing the new data that replaces the old string data.

Example

The following Microsoft® Visual Basic® example creates a new IXMLDOMComment object, and then replaces the first five characters with a new string.

Dim xmlDoc As New Msxml2.DOMDocument
Dim comment As IXMLDOMComment
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set comment = xmlDoc.createComment("Hello World!")
MsgBox comment.xml
comment.replaceData 0, 5, "Goodbye, Cruel"
MsgBox comment.xml
[C/C++]

C/C++ Syntax

HRESULT replaceData(
    long offset,
    long count,
    BSTR data);

Parameters

offset [in]
The offset, in characters, at which to start replacing string data.
count [in]
The number of characters to replace.
data [in]
The new data that replaces the old string data.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value when returning Null.
E_FAIL
The value returned if an error occurs.

See Also

Applies to: IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | IXMLDOMText


reset Method (IXMLDOMNamedNodeMap)

Resets the iterator.

[Script]

Script Syntax

oXMLDOMNamedNodeMap.reset();

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeBook, nodeAttribute, s;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodeBook = xmlDoc.selectSingleNode("//book");
nodeBook.attributes.reset();
nodeAttribute = nodeBook.attributes.nextNode();
alert(nodeAttribute.text);
[Visual Basic]

Visual Basic Syntax

oXMLDOMNamedNodeMap.reset

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeBook As IXMLDOMElement
Dim nodeAttribute As IXMLDOMAttribute
Dim s As String
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodeBook = xmlDoc.selectSingleNode("//book")
nodeBook.Attributes.Reset
Set nodeAttribute = nodeBook.Attributes.nextNode()
MsgBox nodeAttribute.Text
[C/C++]

C/C++ Syntax

HRESULT reset(void);

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

Applies to: IXMLDOMNamedNodeMap


reset Method (IXMLDOMNodeList)

Resets the iterator.

[Script]

Script Syntax

oXMLDOMNodeList.reset();

Example

The following script example creates an IXMLDOMNodeList object and iterates the collection using the nextNode method. It then uses the reset method to reset the iterator to point before the first node in the list.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var objNodeList;
var objNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
objNodeList = xmlDoc.getElementsByTagName("author");
for (var i=0; i<objNodeList.length; i++) {
  objNode = objNodeList.nextNode();
  alert(objNode.text);
}
objNodeList.reset();
objNode = objNodeList.nextNode();
alert(objNode.text);
[Visual Basic]

Visual Basic Syntax

oXMLDOMNodeList.reset

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNodeList object and iterates the collection using the nextNode method. It then uses the reset method to reset the iterator to point before the first node in the list.

Dim xmlDoc As New Msxml2.DOMDocument
Dim objNodeList As IXMLDOMNodeList
Dim objNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set objNodeList = xmlDoc.getElementsByTagName("author")
For i = 0 To (objNodeList.length - 1)
  Set objNode = objNodeList.nextNode
  MsgBox objNode.Text
Next
objNodeList.Reset
Set objNode = objNodeList.nextNode
MsgBox objNode.Text
[C/C++]

C/C++ Syntax

HRESULT reset(void);

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

This method reinitializes the iterator to point before the first node in the IXMLDOMNodeList so that the next call to nextNode returns the first item in the list.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

nextNode Method

Applies to: IXMLDOMNodeList | IXMLDOMSelection


reset Method (IXSLProcessor)

Resets the state of the processor to the state it was in prior to calling transform.

[Script]

Script Syntax

objXSLProcessor.reset();

Example

var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xslProc;
xslDoc.async = false;
xslDoc.load("sample.xsl");
xslt.stylesheet = xslDoc;
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
xslProc = xslt.createProcessor();
xslProc.input = xmlDoc;
xslProc.addParameter("param1", "Hello");
xslProc.transform();
alert(xslProc.output);
xslProc.reset();
alert(xslProc.output);

Sample.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html"/>
    <xsl:param name="param1"/>
    <xsl:template match="/">
        The parameter value was: <xsl:value-of select="$param1"/>
   </xsl:template>
</xsl:stylesheet>
[Visual Basic]

Visual Basic Syntax

objXSLProcessor.reset

Example

Dim xslt As New Msxml2.XSLTemplate
Dim xslDoc As New Msxml2.FreeThreadedDOMDocument
Dim xmlDoc As New Msxml2.DOMDocument
Dim xslProc As IXSLProcessor
xslDoc.async = False
xslDoc.Load "sample.xsl"
Set xslt.stylesheet = xslDoc
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set xslProc = xslt.createProcessor()
xslProc.input = xmlDoc
xslProc.addParameter "param1", "Hello"
xslProc.Transform
MsgBox xslProc.output
xslProc.Reset
MsgBox xslProc.output

Sample.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html"/>
    <xsl:param name="param1"/>
    <xsl:template match="/">
        The parameter value was: <xsl:value-of select="$param1"/>
   </xsl:template>
</xsl:stylesheet>
[C/C++]

C/C++ Syntax

HRESULT reset();

Remarks

It does not reset any other properties, for example, stylesheet or startMode.

The reset method will cause any internally buffered output to be thrown away (that is, it aborts the asynchronous transformation). Calling reset results in the readyState going from READYSTATE_INTERACTIVE back to READYSTATE_LOADED.

A re-entrant call to reset from inside the scope of a call to transform results in that transform call finishing as soon as it can, returning E_FAIL with the error message "User aborted transform."

See Also

Applies to: IXSLProcessor


save Method

Saves an XML document to the specified location.

[Script]

Script Syntax

oXMLDOMDocument.save(destination);

Parameters

destination
An object. The object can represent a file name, an ASP Response object, a DOMDocument object, or a custom object that supports persistence. See Remarks.
[Visual Basic]

Visual Basic Syntax

oXMLDOMDocument.save(destination)

Parameters

destination
An object. The object can represent a file name, an ASP Response object, a DOMDocument object, or a custom object that supports persistence. See Remarks.
[C/C++]

C/C++ Syntax

HRESULT save(
    VARIANT destination);

Parameters

destination [in]
The type of object to save. This object can represent a file name, an ASP Response object, an XML document object, or a custom object that supports persistence. See Remarks.

C/C++ Return Values

S_OK
The value returned if successful.
XML_BAD_ENCODING
The value returned if the document contains a character that does not belong in the specified encoding. The character must use a numeric entity reference. For example, the Japanese Unicode character 20013 does not fit into the encoding Windows-1250 (the Central European alphabet) and therefore must be represented in markup as the numeric entity reference &#20013; or &#x4E2D; This version of save does not automatically convert characters to the numeric entity references.
E_INVALIDARG
The value returned if a string was provided, but it is not a valid file name.
E_ACCESSDENIED
The value returned if a save operation is not permitted.
E_OUTOFMEMORY
The value returned if the save operation must allocate buffers.
(Other values)
Any other file system error can be returned in the save(string) case.

Example

BOOL DOMDocSaveLocation()
{
   BOOL bResult = FALSE;
   IXMLDOMDocument *pIXMLDOMDocument = NULL;
   HRESULT hr;

   try
   {
      _variant_t varString = _T("D:\\sample.xml");
      // Initialize pIXMLDOMDocument (create a DOMDocument).
      // Load document.
      hr = pIXMLDOMDocument->save(varString);
      if(SUCCEEDED(hr))
         bResult = TRUE;
   }
   catch(...)
   {
      DisplayErrorToUser();
   // Release the IXMLDOMDocument interface.
   }
   // Release the IXMLDOMDocument interface when finished with it.
   return bResult;
}

Remarks

The behavior differs based on the object specified by the objTarget parameter.

Object | Description
string Specifies the file name. This must be a file name rather than a URL. The file is created, if necessary, and the contents are replaced entirely with the contents of the saved document. This mode is not intended for use from a secure client, such as Microsoft® Internet Explorer.
    dim xmldoc
    set xmldoc = Server.CreateObject("Msxml2.DOMDocument")
    xmldoc.load("c:\myfile.xml")
    xmldoc.save(Server.MapPath("sample.xml"))

The ASP Response object sends the document back to the client that invoked the ASP script.

    dim xmldoc
    set xmldoc = Server.CreateObject("Msxml2.DOMDocument")
    xmldoc.load(Server.MapPath("sample.xml"))
    xmldoc.save(Response)
IXMLDocument Object Duplicates the original document. It is the equivalent of saving the document and reparsing it. The document goes through full persistence through XML markup, thereby testing the persistability of your XML document.
    <script language="jscript">
        var xmldoc1 = new ActiveXObject("Msxml2.DOMDocument");
        var xmldoc2 = new ActiveXObject("Msxml2.DOMDocument");
        xmldoc1.load("sample.xml");
        xmldoc1.save(xmldoc2.XMLDocument);
    </script>
Custom object supporting persistence | Any other custom COM object that supports QueryInterface for IStream, IPersistStream, or IPersistStreamInit can also be provided here, and the document will be saved accordingly. In the IStream case, the IStream Write method will be called as it saves the document; in the IPersistStream case, IPersistStream Load will be called with an IStream that supports the Read, Seek, and Stat methods.

External entity references in DOCTYPE, ENTITY, NOTATION, and XML namespace declarations are not changed; they point to the original document. A saved XML document might not load if the URLs are not accessible from the location in which you saved the document.

Character encoding is based on the encoding attribute in the XML declaration, such as <?xml version="1.0" encoding="windows-1252"?>. When no encoding attribute is specified, the default setting is UTF-8.

Validation is not performed during save, which can result in an invalid document that does not load again because of a specified document type definition (DTD).

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

XML DOM Persistence

Applies to: DOMDocument


selectNodes Method

Applies the specified pattern-matching operation to this node's context and returns the list of matching nodes as IXMLDOMNodeList.

[Script]

Script Syntax

var objXMLDOMNodeList = oXMLDOMNode.selectNodes(expression);

Parameters

expression
A string specifying the XSL Pattern or XPath query that is to be applied to the context defined by this node. The value of the SelectionLanguage internal property (flag) determines whether an XSL Pattern or XPath query is used. By default, the expression is an XSL Pattern query. The SelectionLanguage internal property (flag) can be set with the setProperty method.

Return Value

An object. Returns a collection of nodes selected by an XSL Pattern or XPath query. If no nodes are selected, an empty collection is returned.

Example

The following script example creates an IXMLDOMNodeList object containing the nodes specified by the pattern string, for example, all of the AUTHOR child nodes with a BOOK parent. It then displays the number of nodes contained in the node list.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeList;
xmlDoc.async = false;
xmlDoc.load("books.xml");
objNodeList = xmlDoc.documentElement.selectNodes("//book");
alert(objNodeList.length);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNodeList = oXMLDOMNode.selectNodes(expression)

Parameters

expression
A string specifying the XSL Pattern or XPath query that is to be applied to the context defined by this node. The value of the SelectionLanguage internal property (flag) determines whether an XSL Pattern or XPath query is used. By default, the expression is an XSL Pattern query. The SelectionLanguage internal property (flag) can be set with the setProperty method.

Return Value

An object. Returns a collection of nodes selected by an XSL Pattern or XPath query. If no nodes are selected, an empty collection is returned.

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNodeList object containing the nodes specified by the query string, for example, all of the AUTHOR child nodes with a BOOK parent. It then displays the number of nodes contained in the node list.

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeList As IXMLDOMNodeList
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set objNodeList = xmlDoc.documentElement.selectNodes("//book")
MsgBox objNodeList.length
[C/C++]

C/C++ Syntax

HRESULT selectNodes(
    BSTR expression,
    IXMLDOMNodeList **resultList);

Parameters

expression [in]
The value of the SelectionLanguage internal property (flag) determines whether an XSL Pattern or XPath query is used. By default, the expression is an XSL Pattern query. The SelectionLanguage internal property (flag) can be set with the setProperty method.
resultList [out, retval]
The list of nodes selected by the XSL Pattern or XPath query. If no nodes are selected by the query, an empty node list is returned.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if resultList is Null.

Remarks

The selectSingleNode method is similar to the selectNodes method, but returns only the first matching node rather than the list of all matching nodes.

IXMLDOMNodeList is live and immediately reflects changes to the nodes that appear in the list.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

Using XSLT from the DOM | setProperty Method | selectSingleNode method | IXMLDOMNodeList | XPath Syntax | Patterns

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


selectSingleNode Method

Applies the specified pattern-matching operation to this node's context and returns the first matching node.

[Script]

Script Syntax

var objXMLDOMNode = oXMLDOMNode.selectSingleNode(queryString);

Parameters

queryString
The string specifying the Extensible Stylesheet Language (XSL) or XPath query that is to be applied to the context defined by this node. The value of the SelectionLanguage internal property (flag) determines whether an XSL or XPath query is used. By default, the expression is an XSL Pattern query. The SelectionLanguage internal property (flag) can be set with the setProperty method.

Return Value

An object. Returns the first node that matches the XSL or XPath query. If no nodes match the query, it returns Null.

Example

The following script example creates an IXMLDOMNode object and sets it to the first instance of an AUTHOR node with a BOOK parent. It then displays the text of the node.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var currNode;
xmlDoc.async = false;
xmlDoc.load("books.xml");
currNode = xmlDoc.documentElement.selectSingleNode("//book");
alert(currNode.text);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oXMLDOMNode.selectSingleNode(queryString)

Parameters

queryString
The string specifying the Extensible Stylesheet Language (XSL) or XPath query that is to be applied to the context defined by this node. The value of the SelectionLanguage internal property (flag) determines whether an XSL or XPath query is used. By default, the expression is an XSL pattern query. The SelectionLanguage internal property (flag) can be set with the setProperty method.

Return Value

An object. Returns the first node that matches the XSL or XPath query. If no nodes match the query, it returns Null.

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMNode object and sets it to the first instance of an AUTHOR node with a BOOK parent. It then displays the text of the node.

Dim xmlDoc As New Msxml2.DOMDocument
Dim currNode As IXMLDOMNode
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set currNode = xmlDoc.documentElement.selectSingleNode("//book")
MsgBox currNode.Text
[C/C++]

C/C++ Syntax

HRESULT selectSingleNode(
    BSTR queryString,
    IXMLDOMNode **resultNode);

Parameters

queryString [in]
The string specifying the XSL or XPath query that is to be applied to the context defined by this node. The value of the SelectionLanguage internal property (flag) determines whether an XSL or XPath query is used. By default, the expression is an XSL pattern query. The SelectionLanguage internal property (flag) can be set with the setProperty method.
resultNode [out, retval]
The first node that is selected by the XPath query. Returns Null if no nodes result from the query.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned if there is no match.
E_INVALIDARG
The value returned if resultNode is Null.

Remarks

The selectSingleNode method is similar to the selectNodes method, but returns only the first matching node rather than the list of all matching nodes.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

Using XSLT from the DOM | selectNodes Method | setProperty Method | XPath Syntax

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


send Method (IXMLHTTPRequest)

Sends an HTTP request to the server and receives a response.

[Script]

Script Syntax

oXMLHttpRequest.send(varBody);

Parameters

varBody
A variant. Case-insensitive name.

Example

xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp.open("GET", "http://localhost/sample.xml", false);
xmlhttp.send();
alert(xmlhttp.responseXML.xml);
[Visual Basic]

Visual Basic Syntax

oXMLHttpRequest.send(varBody)

Parameters

varBody
A variant. Case-insensitive name.

Example

Dim xmlhttp As New Msxml2.xmlhttp
xmlhttp.open "GET", "http://localhost/sample.xml", False
xmlhttp.send
MsgBox xmlhttp.responseXML.xml
[C/C++]

C/C++ Syntax

HRESULT send(VARIANT varBody);

Parameters

varBody [in, optional]
The body of the message being sent with the request.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

This method is synchronous or asynchronous, depending on the value of the bAsync parameter in the open method call. If open is called with bAsync == False, this call does not return until the entire response is received or the protocol stack times out. If open is called with bAsync == True, this call returns immediately.

This method takes one optional parameter, which is the requestBody to use. The acceptable VARIANT input types are BSTR, SAFEARRAY of UI1 (unsigned bytes), IDispatch to an XML Document Object Model (DOM) object, and IStream *. You can use only chunked encoding (for sending) when sending IStream * input types. The component automatically sets the Content-Length header for all but IStream * input types.

If the input type is a BSTR, the response is always encoded as UTF-8. The caller must set a Content-Type header with the appropriate content type and include a charset parameter.

If the input type is a SAFEARRAY of UI1, the response is sent as is without additional encoding. The caller must set a Content-Type header with the appropriate content type.

If the input type is an XML DOM object, the response is encoded according to the encoding attribute on the <? declaration in the document. If there is no XML declaration or encoding attribute, UTF-8 is assumed.

If the input type is an IStream *, the response is sent as is without additional encoding. The caller must set a Content-Type header with the appropriate content type.

See Also

open Method

Applies to: IXMLHTTPRequest


send Method (ServerXMLHTTP/IServerXMLHTTPRequest)

Sends an HTTP request to the server and receives a response.

[Script]

Script Syntax

oServerXMLHttpRequest.send(varBody);

Parameters

varBody
The body of the message being sent with the request.

Example

<%@language=JScript%>
<%
var srvXmlHttp
srvXmlHttp = Server.CreateObject("Msxml2.ServerXMLHTTP");
srvXmlHttp.Open ("GET", "http://myserver/myresponse.asp", false);
srvXmlHttp.Send();
newsElement = srvXmlHttp.responseXML.selectSingleNode("/news/story1");
%>

<html>
<body>
<p>Top News Story<p>
<%Response.write(newsElement.text);%>
</body>
</html>
[Visual Basic]

Visual Basic Syntax

oServerXMLHttpRequest.send(varBody)

Parameters

varBody
The body of the message being sent with the request.

Example

Dim xmlServerHttp As New Msxml2.ServerXMLHTTP
xmlServerHttp.open "GET", "http://localhost/sample.xml", False
xmlServerHttp.send
MsgBox xmlServerHttp.responseXML.xml
[C/C++]

C/C++ Syntax

HRESULT send(VARIANT varBody);

Parameters

varBody [in, optional]
The body of the message being sent with the request.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

This method is synchronous or asynchronous, depending on the value of the bAsync parameter in the open method call. If open is called with bAsync == False, this call does not return until the entire response is received or the protocol stack times out. If open is called with bAsync == True, this call returns immediately.

This method takes one parameter, which is the requestBody to use. The acceptable VARIANT input types are BSTR, SAFEARRAY of UI1 (unsigned bytes), IDispatch to an XML Document Object Model (DOM) object, and IStream *. You can only use chunked encoding (for sending) when sending IStream *input types. The component automatically sets the Content-Length header for all but IStream *input types.

If the input type is a BSTR, the response is always encoded as UTF-8. The caller must set a Content-Type header with the appropriate content type and include a charset parameter.

If the input type is a SAFEARRAY of UI1, the response is sent as is without additional encoding. The caller must set a Content-Type header with the appropriate content type.

If the input type is an XMLDOM object, the response is encoded according to the encoding attribute on the <? XML declaration in the document. If there is no XML declaration or encoding attribute, UTF-8 is assumed.

If the input type is an IStream *, the response is sent as is without additional encoding. The caller must set a Content-Type header with the appropriate content type.

Important You cannot call multiple send methods for a single open method. Instead, for each send method, you must call a corresponding open method. For example:
osrvXmlHttp.open()
osrvXmlHttp.send()
osrvXmlHttp.open()
osrvXmlHttp.send()

See Also

open Method

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


setAttribute Method

Sets the value of the named attribute.

[Script]

Script Syntax

oXMLDOMElement.setAttribute(name, value);

Parameters

name
The string specifying the name of the attribute. If the attribute with that name already exists, its value is changed. If the attribute with that name does not exist, it is created.
value
The variant that supplies the value for the named attribute.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeBook;
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodeBook = xmlDoc.selectSingleNode("//book");
nodeBook.setAttribute("PublishDate", String(Date()))
alert(nodeBook.getAttribute("PublishDate"));
[Visual Basic]

Visual Basic Syntax

oXMLDOMElement.setAttribute(name, value)

Parameters

name
The string specifying the name of the attribute. If the attribute with that name already exists, its value is changed. If the attribute with that name does not exist, it is created.
value
The variant that supplies the value for the named attribute.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeBook As IXMLDOMElement
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodeBook = xmlDoc.selectSingleNode("//book")
nodeBook.setAttribute "PublishDate", Now
MsgBox nodeBook.getAttribute("PublishDate")
[C/C++]

C/C++ Syntax

HRESULT setAttribute(
    BSTR name,
    VARIANT value);

Parameters

name [in]
The name of the attribute. If an attribute with that name already exists, its value is changed. If an attribute with that name does not exist, it is created.
value [in]
The value for the named attribute.

C/C++ Return Values

S_OK
The value returned if successful.
E_FAIL
The value returned if an error occurs.

C/C++ Example

See the example in the getAttribute method.

Remarks

If an attribute with the supplied name already exists, this method changes its value to the supplied value parameter. The supplied string is not parsed, so any markup, such as syntax intended to be recognized as an entity reference, is treated as literal text and must be appropriately escaped by the implementation when it is written out.

To assign an attribute value that contains entity references, the user must create IXMLDOMAttribute plus any IXMLDOMText and IXMLDOMEntityReference objects, build the appropriate subtree, and call the setAttributeNode method.

See Also

IXMLDOMAttribute | IXMLDOMText | IXMLDOMEntityReference | setAttributeNode method

Applies to: IXMLDOMElement


setAttributeNode Method

Sets or updates the supplied attribute node on this element.

[Script]

Script Syntax

var objXMLDOMAttribute = oXMLDOMElement.XMLDOMElement(DOMAttribute);

Parameters

DOMAttribute
An object that contains the attribute node to be associated with this element.

Return Value

An object. Returns Null unless the new attribute replaces an existing attribute with the same name, in which case this method returns the previous, replaced attribute node.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeBook, nodePublishDate;
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodePublishDate = xmlDoc.createAttribute("PublishDate");
nodePublishDate.value = String(Date());
nodeBook = xmlDoc.selectSingleNode("//book");
nodeBook.setAttributeNode(nodePublishDate);
alert(nodeBook.getAttribute("PublishDate"));
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMAttribute = oXMLDOMElement.XMLDOMElement(DOMAttribute)

Parameters

DOMAttribute
An object that contains the attribute node to be associated with this element.

Return Value

An object. Returns Null unless the new attribute replaces an existing attribute with the same name, in which case this method returns the previous, replaced attribute node.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeBook As IXMLDOMElement
Dim nodePublishDate As IXMLDOMAttribute
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodePublishDate = xmlDoc.createAttribute("PublishDate")
nodePublishDate.Value = Now
Set nodeBook = xmlDoc.selectSingleNode("//book")
nodeBook.setAttributeNode nodePublishDate
MsgBox nodeBook.getAttribute("PublishDate")
[C/C++]

C/C++ Syntax

HRESULT setAttributeNode(
    IXMLDOMAttribute *DOMAttribute,
    IXMLDOMAttribute **attributeNode);

Parameters

DOMAttribute [in]
An attribute node that is to be associated with this element.
attributeNode [out, retval]
Null unless the new attribute replaces an existing attribute with the same name, in which case this method returns the previous, replaced attribute node.

C/C++ Return Values

S_OK
The value returned if successful.
E_FAIL
The value returned if an error occurs.

C/C++ Example

See the example in the getAttributeNode method.

Remarks

You cannot add an existing attribute to an element until you first remove it from its previous element. Also, you cannot add a namespace-qualified attribute when it uses the same prefix as another attribute with a different namespaceURI.

See Also

namespaceURI Property

Applies to: IXMLDOMElement


setNamedItem Method

Adds the supplied node to the collection.

[Script]

Script Syntax

var objXMLDOMNode = oIXMLDOMNamedNodeMap.setNamedItem(newItem);

Parameters

newItem
The object containing the attribute to be added to the collection.

Return Value

An object. Returns the attribute successfully added to the collection.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeBook, nodePublishDate;
xmlDoc.async = false;
xmlDoc.load("books.xml");
nodePublishDate = xmlDoc.createAttribute("PublishDate");
nodePublishDate.value = String(Date());
nodeBook = xmlDoc.selectSingleNode("//book");
nodeBook.attributes.setNamedItem(nodePublishDate);
alert(nodeBook.getAttribute("PublishDate"));
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMNode = oIXMLDOMNamedNodeMap.setNamedItem(newItem)

Parameters

newItem
The object containing the attribute to be added to the collection.

Return Value

An object. Returns the attribute successfully added to the collection.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeBook As IXMLDOMElement
Dim nodePublishDate As IXMLDOMAttribute
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set nodePublishDate = xmlDoc.createAttribute("PublishDate")
nodePublishDate.Value = Now
Set nodeBook = xmlDoc.selectSingleNode("//book")
nodeBook.Attributes.setNamedItem nodePublishDate
MsgBox nodeBook.getAttribute("PublishDate")
[C/C++]

C/C++ Syntax

HRESULT setNamedItem(
    IXMLDOMNode *newItem,
    IXMLDOMNode **nameItem);

Parameters

newItem [in]
An attribute to be added to the collection.
nameItem [out, retval]
An attribute successfully added to the collection. If Null, no object is created.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if newItem is Null.
E_FAIL
The value returned if an error occurs.

C/C++ Example

HRESULT hr;
IXMLDOMDocument *pIXMLDOMDocument = NULL;
IXMLDOMNode *pIXMLDOMNode = NULL;
IXMLDOMNamedNodeMap *pIXMLDOMNamedNodeMap = NULL;
BSTR bstrAttributeName = ::SysAllocString(_T("dateModified"));
IXMLDOMAttribute *pIXMLDOMAttribute = NULL;
IXMLDOMElement *pIXMLDOMElement = NULL;

try
{
   // Create an instance of DOMDocument and initialize pIXMLDOMDocument.
   // Load/create an XML fragment.
   hr = m_pIXMLDOMDocument->get_documentElement(&pIXMLDOMElement);
   SUCCEEDED(hr) ? 0 : throw hr;

   if(pIXMLDOMElement)
   {
      hr = pIXMLDOMElement->get_attributes(&pIXMLDOMNamedNodeMap);
      if(SUCCEEDED(hr) && pIXMLDOMNamedNodeMap)
      {
         hr = m_pIXMLDOMDocument->createAttribute(bstrAttributeName, &pIXMLDOMAttribute);
         if(SUCCEEDED(hr) && pIXMLDOMAttribute)
         {
            hr = pIXMLDOMAttribute->put_nodeValue(_variant_t(_T("year 2000")));
            hr = pIXMLDOMNamedNodeMap->setNamedItem(pIXMLDOMAttribute, &pIXMLDOMNode);
            if(SUCCEEDED(hr) && pIXMLDOMNode)
            {
               pIXMLDOMNode->Release();
               pIXMLDOMNode = NULL;
            }
            pIXMLDOMAttribute->Release();
            pIXMLDOMAttribute = NULL;
         }
         pIXMLDOMNamedNodeMap->Release();
         pIXMLDOMNamedNodeMap = NULL;
      }
      pIXMLDOMElement->Release();
      pIXMLDOMElement = NULL;
   }
   ::SysFreeString(bstrAttributeName);
   bstrAttributeName = NULL;
}
catch(...)
{
   if(bstrAttributeName)
      ::SysFreeString(bstrAttributeName);
   if(pIXMLDOMElement)
      pIXMLDOMElement->Release();
   if(pIXMLDOMNamedNodeMap)
      pIXMLDOMNamedNodeMap->Release();
   if(pIXMLDOMAttribute)
      pIXMLDOMAttribute->Release();
   if(pIXMLDOMNode)
      pIXMLDOMNode->Release();
   DisplayErrorToUser();
}
// Release pIXMLDOMDocument when finished with it.

Remarks

If an attribute already exists with the name in IXMLDOMNode, the supplied replaces the existing attribute. The attribute name appears in its IXMLDOMNode property.

If the newItem node type is not NODE_ATTRIBUTE, setNamedItem returns an error. For example, it is not possible to modify entities or notations, which are read-only.

See Also

IXMLDOMNode

Applies to: IXMLDOMNamedNodeMap


setOption Method

Sets one of the following options:

SXH_OPTION_URL_CODEPAGE
The code page used to convert the Unicode URL string specified in the open method.
SXH_OPTION_ESCAPE_PERCENT_IN_URL
The escaping of the % character.
SXH_OPTION_IGNORE_SERVER_SSL_CERT_ERROR_FLAGS
Flags that can be set to ignore problems with the server's Secure Sockets Layer (SSL) certificate.
SXH_OPTION_SELECT_CLIENT_SSL_CERT
The name of the client certificate specified in your local store.
[Script]

Script Syntax

oServerXMLHTTPRequest.setOption(option) = varValue;

Parameters

option
The option whose value is to be set. For a list of available options and a description of how to use those options, see Remarks.
[Visual Basic]

Visual Basic Syntax

oServerXMLHTTPRequest.setOption(option) = varValue

Parameters

option
The option whose value is to be set. For a list of available options and a description of how to use those options, see Remarks.
[C/C++]

C/C++ Syntax

HRESULT setOption(SERVERXMLHTTP_OPTION option, VARIANT value);

Parameters

option [in]
The option whose value is to be set. For a list of available options and a description of how to use those options, see Remarks.
value [in]
The value to which the specified option is to be set.

C/C++ Return Values

S_OK
Value returned if successful.

Remarks

The following table lists the options available to the setOption method.

Option Description
0 SXH_OPTION_URL_CODEPAGE

By default, CP_UTF8 is the code page used to convert the Unicode URL string (specified in the open method) to a single-byte representation.

The SXH_OPTION_URL_CODEPAGE option allows the client to override this default with a different code page value. The client should specify an unsigned integer value for the code page.
1 SXH_OPTION_ESCAPE_PERCENT_IN_URL

By default, escaping unsafe ANSI characters in the URL (for example, " " -> "%20") does not escape the % character itself.

The SXH_OPTION_ESCAPE_PERCENT_IN_URL option allows the client to change this behavior. The client should specify a Boolean True/False value for this option.
2 SXH_OPTION_IGNORE_SERVER_SSL_CERT_ERROR_FLAGS

The SXH_OPTION_IGNORE_SERVER_SSL_CERT_ERROR_FLAGS option is a DWORD mask of various flags that can be set to change this default behavior. The default value is to ignore all problems. You must set this option before calling the send method. The flags are as follows:

SXH_SERVER_CERT_IGNORE_UNKNOWN_CA = 256

Unknown certificate authority

SXH_SERVER_CERT_IGNORE_WRONG_USAGE = 512

Malformed certificate such as a certificate with no subject name.

SXH_SERVER_CERT_IGNORE_CERT_CN_INVALID = 4096

Mismatch between the visited hostname and the certificate name being used on the server.

SXH_SERVER_CERT_IGNORE_CERT_DATE_INVALID = 8192

The date in the certificate is invalid or has expired.

SXH_SERVER_CERT_IGNORE_ALL_SERVER_ERRORS = 13056

All certificate errors.

To turn off a flag, you subtract it from the default value, which is the sum of all flags. For example, to catch an invalid date in a certificate, you turn off the SXH_SERVER_CERT_IGNORE_CERT_DATE_INVALID flag as follows:

shx.setOption(2) = (shx.getOption(2) _
                    - SXH_SERVER_CERT_IGNORE_CERT_DATE_INVALID)
3 SXH_OPTION_SELECT_CLIENT_SSL_CERT

By default, the value of this option is an empty string (""), which means pick the first certificate in the local store to send if the server requests a client certificate.

The SXH_OPTION_SELECT_CLIENT_SSL_CERT option is a string that lets you select which client certificate from the local store should be sent. You must set this option before calling the send method. The following example sets the client certificate option to request the client certificate named "MSXML":

certName = shx.getOption(3)

See Also

getOption Method | open Method

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


setProperty Method

Sets the SelectionLanguage, ServerHTTPRequest, or SelectionNamespaces internal properties (flags).

Important For servers running on an intranet, the ServerHTTPRequest property requires you to run a proxycfg.exe utility to configure WinHTTP's proxy settings. They cannot be configured through the Microsoft® Windows® Control Panel. To download the proxy configuration utility, go to the XML Development Center's Other Resources WinHTTP Proxy Configuration Utility page. For instructions about running the proxycfg.exe utility, see Using the WinHTTP Proxy Configuration Utility. After you have run the proxycfg.exe tool and updated the registry, the previous registry settings cannot be restored.
[Script]

Script Syntax

objXMLDOMDocument2.setProperty(name, value);

Parameters

name
The name of the property to be set. For a list of properties that can be set using this method, see Remarks.
value
The value of the specified property. For a list of property values that can be set using this method, see Remarks.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var selection;
xmlDoc.loadXML("<Customer><Name>Microsoft</Name></Customer>");
xmlDoc.setProperty("SelectionLanguage", "XPath");
selection = xmlDoc.selectNodes("Customer/Name");
alert(selection.expr + " -- " + selection.item(0).xml);

The preceding message box displays "Customer/Name -- <Name>Microsoft</Name>".

selection.expr = "/Customer";
alert(selection.expr + " -- " + selection.item(0).xml);

The preceding message box displays "/Customer –-<Customer><Name>Microsoft</Name></Customer>".

[Visual Basic]

Visual Basic Syntax

objXMLDOMDocument2.setProperty(name, value)

Parameters

name
The name of the property to be set. For a list of properties that can be set using this method, see Remarks.
value
The value of the specified property. For a list of property values that can be set using this method, see Remarks.

Example

Dim xmldoc As New Msxml2.DOMDocument
Dim selection As Msxml2.IXMLDOMSelection

xmldoc.loadXML ("<Customer><Name>Microsoft</Name></Customer>")
xmldoc.setProperty "SelectionLanguage", "XPath"
Set selection = xmldoc.selectNodes("Customer/Name")
MsgBox selection.expr + " -- " + selection.Item(0).xml

The preceding message box displays "Customer/Name -- <Name>Microsoft</Name>".

selection.expr = "/Customer"
MsgBox selection.expr + " -- " + selection.Item(0).xml

The preceding message box displays "/Customer –-<Customer><Name>Microsoft</Name></Customer>".

[C/C++]

C/C++ Syntax

HRESULT setProperty (BSTR name, VARIANT value);

Parameters

name [in]
The name of the property to be set. For a list of properties that can be set using this method, see Remarks.
value [in]
The value of the specified property. For a list of property values that can be set using this method, see Remarks.

C/C++ Return Values

S_OK
Value returned if successful.
E_FAIL
Value returned if name or value is invalid.

Remarks

The following table shows the properties that you can set using this method. Existing properties from DOMDocument are not accessible through this method. White space is not stripped or normalized in property names or values.

Name Value
SelectionLanguage internal property (flag) "XPath" or "XSLPattern"

The SelectionLanguage property defaults to "XSLPattern". This property indicates the type of query the user plans to pass into selectNodes or selectSingleNode. "XSLPattern" is the default for backward compatibility. This flag applies to all nodes whose ownerDocument property points to this document object. Therefore, if a given node is moved to a different document, its selectNode behavior may change depending on the SelectionLanguage setting in the new document. The following Jscript example on the client shows how to set the SelectionLanguage to XPath for the xmldoc object.

var xmldoc = new ActiveXObject("Msxml2.DOMDocument");
var selection;

xmldoc.loadXML ("<Customer><Name>Microsoft</Name></Customer>");
xmldoc.setProperty("SelectionLanguage", "XPath");
selection = xmldoc.selectNodes("Customer/Name");
alert(selection.expr + " -- " + selection.item(0).xml);
ServerHTTPRequest internal property (flag) True/False value indicating if the "server-safe" ServerXMLHTTP component should be used to load a document to a server. This only supports synchronous loading; thus, the async property must be set to False when ServerXMLHTTP is set to True.

For example:

<%@language=JScript%>
<%
var xmlDoc;
xmlDoc = Server.CreateObject("Msxml2.DomDocument");
xmlDoc.async = false;
xmlDoc.setProperty("ServerHTTPRequest", true);
xmlDoc.load(http://myserver.com);
%>
SelectionNamespaces internal property (flag) A space delimited set of Namespace names.

For example:

oDomDocument.setProperty("SelectionNamespaces",
"xmlns:example1='http://myserver.com'
xmlns:example2='http://yourserver.com'");

With the SelectionNamespaces internal property (flag), the selectSingleNode method and selectNodes method can now use qualified names.

See Also

selectSingleNode Method | selectNodes Method

Applies to: IXMLDOMDocument2


setRequestHeader Method (IXMLHTTPRequest)

Specifies the name of an HTTP header.

[Script]

Script Syntax

oXMLHttpRequest.setRequestHeader(bstrHeader, bstrValue);

Parameters

bstrHeader
A string. A header name to set; for example, "depth". This parameter should not contain a colon and should be the actual text of the HTTP header.
bstrValue
A string. The value of the header; for example, "infinity".

Example

The following script example posts a DOMDocument to an Active Server Page (ASP) on a server and returns the result as a new XML document.

<HTML>
<HEAD>
</HEAD>
<BODY LANGUAGE=javascript onload="return onload()">
<TABLE border='2' align='center'>
<TR><TD width="150" align='center'>
   <LABEL>Name</LABEL>
   </TD><TD>
   <input name='Customername' type="edit"/>
</TD></TR>
<TR><TD width="150" align='center'>
   <LABEL>Telephone number</LABEL>
   </TD><TD>
   <input type="edit" name='telno'/>
</TD></TR>
</TABLE>
<TABLE align='center'>
   <TR><TD width="150" align='center'>
      <input type='button' value='send Information' align='center' onclick='sendinfo()'/>
   </TD></TR>
</TABLE>
<script language="vbscript">
function onload()
   Set pi = mydata.createProcessingInstruction("xml", "version='1.0' encoding='UTF-8'")
   mydata.insertBefore pi, mydata.firstChild
end function

function sendinfo()
   Dim myhttp

   ' Do validation of input data before sending it.
   if(not(Customername.value = ""))   then
      mydata.documentElement.getElementsByTagName("Name").item(0).text =Customername.value
      mydata.documentElement.getElementsByTagName("TelNo").item(0).text =telno.value
      Set myhttp=CreateObject("Msxml2.XMLHTTP")
      myhttp.open "GET", "http://SamplesServer/httpreqserver.asp", false
      ' Simulate message sent by a custom user agent.
      myhttp.setRequestHeader "User-Agent", "MyCustomUser"
      mydata.async=false
      myhttp.send mydata.XMLDocument
      alert myhttp.responseText
   else
      alert "invalid data"
   end if
end function
</script>
</BODY>
</HTML>
<XML id="mydata">
<MyStruct>
   <Name/>
   <TelNo/>
</MyStruct>
</XML>

File Name: http://SamplesServer/httpreqserver.asp

<%@ language=javascript %>
<%
   Response.Expires = -1000;
   // Load the posted XML document.
   var doc = Server.CreateObject("Msxml2.DOMDocument");
   doc.async=false;
   doc.load(Request);
   var result = Server.CreateObject("Msxml2.DOMDocument");
   // Now process the order and build the result document.
   var userAgent = Request.ServerVariables("HTTP_User-Agent");
   var OutputString="Data for "+    doc.documentElement.childNodes.item(0).text+" Added";
   Response.ContentType = "text/xml";
   if(userAgent == "MyCustomUser")
   {
      result.loadXML("<result>" + OutputString +" </result>");
      var pi = result.createProcessingInstruction("xml", "version='1.0'");
      result.insertBefore( pi, result.firstChild);
      result.save(Response);
   }
   else
   {
      Response.Write("<P><B>" + OutputString+" </B></P>");
   }
%>

Output

<?xml version="1.0"?>
<result>Data for [input name] Added</result>
[Visual Basic]

Visual Basic Syntax

oXMLHttpRequest.setRequestHeader(bstrHeader, bstrValue)

Parameters

bstrHeader
A string. A header name to set; for example, "depth". This parameter should not contain a colon and should be the actual text of the HTTP header.
bstrValue
A string. The value of the header; for example, "infinity".
[C/C++]

C/C++ Syntax

HRESULT setRequestHeader(BSTR bstrHeader, BSTR bstrValue);

Parameters

bstrHeader [in]
A header name to set; for example, "depth". This parameter should not contain a colon and should be the actual text of the HTTP header.
bstrValue [in]
The value of the header; for example, "infinity".

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

If another header already exists with this name, it is replaced.

See Also

getResponseHeader Method

Applies to: IXMLHTTPRequest


setRequestHeader Method (ServerXMLHTTP/IServerXMLHTTPRequest)

Specifies the name of an HTTP header.

Remarks

If another header already exists with this name, it is replaced.

[Script]

Script Syntax

oXMLServerHTTPRequest.setRequestHeader(bstrHeader, bstrValue);

Parameters

bstrHeader
The header name to set; for example, "depth". This parameter should not contain a colon and should be the actual text of the HTTP header.
bstrValue
The value of the header; for example, "infinity".
[Visual Basic]

Visual Basic Syntax

oXMLServerHTTPRequest.setRequestHeader(bstrHeader, bstrValue)

Parameters

bstrHeader
The header name to set; for example, "depth". This parameter should not contain a colon and should be the actual text of the HTTP header.
bstrValue
The value of the header; for example, "infinity".
[C/C++]

C/C++ Syntax

HRESULT setRequestHeader(BSTR bstrHeader, BSTR bstrValue);

Parameters

bstrHeader [in]
The header name to set; for example, "depth". This parameter should not contain a colon and should be the actual text of the HTTP header.
bstrValue [in]
The value of the header; for example, "infinity".

C/C++ Return Values

S_OK
The value returned if successful.

See Also

getResponseHeader Method

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


setStartMode Method

Performs subsets of larger XSL Transformations (XSLT) by selecting the XSLT mode with which to start. This minimizes the amount of XSLT processing.

The default value of the start mode is the empty string, "".

Example

var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xslProc;
xslDoc.async = false;
xslDoc.load("sample2.xsl");
xslt.stylesheet = xslDoc;
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
xslProc = xslt.createProcessor();
xslProc.input = xmlDoc;
xslProc.setStartMode("view");
xslProc.transform();
alert(xslProc.output);

File Name: Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[Script]

Script Syntax

objXSLProcessor.setStartMode(mode, namespaceURI);

Parameters

mode
The desired mode as a string. It must be the base name part of the qualified name.
namespaceURI
(optional) The full namespace URI to fully qualify the start mode name.
[Visual Basic]

Visual Basic Syntax

objXSLProcessor.setStartMode(mode, namespaceURI)

Parameters

mode
The desired mode as a string. It must be the base name part of the qualified name.
namespaceURI
(optional) The full namespace URI to fully qualify the start mode name.

Example

Dim xslt As New Msxml2.XSLTemplate
Dim xslDoc As New Msxml2.FreeThreadedDOMDocument
Dim xmlDoc As New Msxml2.DOMDocument
Dim xslProc As IXSLProcessor
xslDoc.async = False
xslDoc.Load "sample2.xsl"
Set xslt.stylesheet = xslDoc

xmlDoc.async = False
xmlDoc.Load "books.xml"

Set xslProc = xslt.createProcessor()
xslProc.input = xmlDoc
xslProc.setStartMode "view"

xslProc.Transform
MsgBox xslProc.output

File Name: Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[C/C++]

C/C++ Syntax

HRESULT setStartMode(BSTR mode, BSTR namespaceURI);

Parameters

mode [in]
The desired mode as a string. It must be the base name part of the qualified name.
namespaceURI [in, optional]
The full namespace URI to fully qualify the start mode name.

C/C++ Return Values

S_OK
Success
E_FAIL
The value returned if ready State is READYSTATE_INTERACTIVE.
E_INVALIDARG
The value returned if the mode base name contains a colon character or is an invalid name.

Remarks

Using setStartMode is essentially the same as an XSLT style sheet that starts with the following rule.

<xsl:template match="/">
   <xsl:apply-templates select="*" mode="{mode}"/>
</xsl:template>

See Also

Applies to: IXSLProcessor

Other Resources Other Resources

W3C Qualified Names section of the XSL Transformations (XSLT) Version 1.0 | W3C Namespaces in XML Recommendation


setTimeouts Method

Specifies timeout settings for resolving the domain name, establishing the connection to the server, sending the data, and receiving the response. The timeout parameters of the setTimeouts method are specified in milliseconds, so a value of 1000 would represent 1 second. A value of zero represents an infinite timeout. There are four separate timeout values: resolveTimeout, connectTimeout, sendTimeout and receiveTimeout. When calling the setTimeouts method, all four values must be specified. The timeouts are applied at the Winsock layer.

[Script]

Script Syntax

oServerXMLHTTPRequest.setTimeouts(resolveTimeout, connectTimeout,
 sendTimeout, receiveTimeout);

Parameters

resolveTimeout
A long integer. The value is applied to mapping host names (such as "www.microsoft.com") to IP addresses; the default value is infinite, meaning no timeout.
connectTimeout
A long integer. The value is applied to establishing a communication socket with the target server, with a default timeout value of 60 seconds.
sendTimeout
A long integer. The value applies to sending an individual packet of request data (if any) on the communication socket to the target server. A large request sent to a server will normally be broken up into multiple packets; the send timeout applies to sending each packet individually. The default value is 5 minutes.
receiveTimeout
A long integer. The value applies to receiving a packet of response data from the target server. Large responses will be broken up into multiple packets; the receive timeout applies to fetching each packet of data off the socket. The default value is 60 minutes.

Example

var xmlServerHttp = new ActiveXObject("Msxml2.ServerXMLHTTP");
var lResolve = 5 * 1000;
var lConnect = 5 * 1000;
var lSend = 15 * 1000;
var lReceive = 15 * 1000;
xmlServerHttp.setTimeouts(lResolve, lConnect, lSend, lReceive);
xmlServerHttp.open("GET", "http://localhost/sample.xml", false);
xmlServerHttp.send();
[Visual Basic]

Visual Basic Syntax

oServerXMLHTTPRequest.setTimeouts(resolveTimeout, connectTimeout,
sendTimeout, receiveTimeout)

Parameters

resolveTimeout
A long integer. The value is applied to mapping host names (such as "www.microsoft.com") to IP addresses; the default value is infinite, meaning no timeout.
connectTimeout
A long integer. The value is applied to establishing a communication socket with the target server, with a default timeout value of 60 seconds.
sendTimeout
A long integer. The value applies to sending an individual packet of request data (if any) on the communication socket to the target server. A large request sent to a server will normally be broken up into multiple packets; the send timeout applies to sending each packet individually. The default value is 5 minutes.
receiveTimeout
A long integer. The value applies to receiving a packet of response data from the target server. Large responses will be broken up into multiple packets; the receive timeout applies to fetching each packet of data off the socket. The default value is 60 minutes.

Example

Dim xmlServerHttp As New Msxml2.ServerXMLHTTP
Dim lResolve, lConnect, lSend, lReceive As Long
lResolve = 5 * 1000
lConnect = 5 * 1000
lSend = 15 * 1000
lReceive = 15 * 1000
xmlServerHttp.setTimeouts lResolve, lConnect, lSend, lReceive
xmlServerHttp.open "GET", "http://localhost/sample.xml", False
xmlServerHttp.send
[C/C++]

C/C++ Syntax

HRESULT setTimeouts (long resolveTimeout, long connectTimeout,
 long sendTimeout, long receiveTimeout)

Parameters

resolveTimeout [in]
A long integer. The value is applied to mapping host names (such as "www.microsoft.com") to IP addresses; the default value is infinite, meaning no timeout.
connectTimeout [in]
A long integer. The value is applied to establishing a communication socket with the target server, with a default timeout value of 60 seconds.
sendTimeout [in]
A long integer. The value applies to sending an individual packet of request data (if any) on the communication socket to the target server. A large request sent to a server will normally be broken up into multiple packets; the send timeout applies to sending each packet individually. The default value is 5 minutes.
receiveTimeout [in]
A long integer. The value applies to receiving a packet of response data from the target server. Large responses will be broken up into multiple packets; the receive timeout applies to fetching each packet of data off the socket. The default value is 60 minutes.

C/C++ Return Values

S_OK
Value returned if successful.

Remarks

The setTimeouts method should be called before the open method. None of the parameters is optional.

See Also

open Method

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


splitText Method

Splits this text node into two text nodes at the specified offset and inserts the new text node into the tree as a sibling that immediately follows this node.

[Script]

Script Syntax

var objXMLDOMText = oXMLDOMText.splitText(offset);

Parameters

offset
A long integer. The number of characters at which to split this text node into two nodes, starting from zero.

Return Value

An object. Returns the new text node.

Example

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var nodeRoot, nodeText, newNodeText;
xmlDoc.async = false;
xmlDoc.loadXML("<root>Hello World!</root>");
nodeRoot = xmlDoc.documentElement;
nodeText = nodeRoot.firstChild;
alert(nodeRoot.childNodes.length);
newNodeText = nodeText.splitText(6);
alert(nodeRoot.childNodes.length);
[Visual Basic]

Visual Basic Syntax

Set objXMLDOMText = oXMLDOMText.splitText(offset)

Parameters

offset
A long integer. The number of characters at which to split this text node into two nodes, starting from zero.

Return Value

An object. Returns the new text node.

Example

Dim xmlDoc As New Msxml2.DOMDocument
Dim nodeRoot As IXMLDOMElement
Dim nodeText As IXMLDOMText
Dim newNodeText As IXMLDOMText
xmlDoc.async = False
xmlDoc.loadXML "<root>Hello World!</root>"
Set nodeRoot = xmlDoc.documentElement
Set nodeText = nodeRoot.firstChild
MsgBox nodeRoot.childNodes.length
Set newNodeText = nodeText.splitText(6)
MsgBox nodeRoot.childNodes.length
[C/C++]

C/C++ Syntax

HRESULT splitText(
    long offset,
    IXMLDOMText **rightHandTextNode);

Parameters

offset [in]
The number of characters at which to split this text node into two nodes, starting from zero.
rightHandTextNode [out, retval]
The new text node.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value when returning Null.
E_FAIL
The value returned if an error occurs.

C/C++ Example

IXMLDOMText *pIXMLDOMTextTemp = NULL;
IXMLDOMText *pIXMLDOMText = NULL;
IXMLDOMNode *pIXMLDOMNodeTemp = NULL;
IXMLDOMElement *pIXMLDOMElement = NULL;
IXMLDOMNode *pIXMLDOMNode = NULL;
DOMNodeType DOMNodeTyp;
VARIANT varValue;
HRESULT hr;

try
{
   // Create an instance of DOMDocument and initialize pIXMLDOMDocument.
   // Load/create an XML fragment.
   hr = pIXMLDOMDocument->get_documentElement(&pIXMLDOMElement);
   SUCCEEDED(hr) ? 0 : throw hr;

   if(pIXMLDOMElement)
   {
      hr = pIXMLDOMElement->QueryInterface(IID_IXMLDOMNode, (void
            **)&pIXMLDOMNode);
      SUCCEEDED(hr) ? 0 : throw hr;

      pIXMLDOMElement->Release();
      pIXMLDOMElement = NULL;

      while(pIXMLDOMNode)
      {
         hr = pIXMLDOMNode->get_nodeType(&DOMNodeTyp);
         if(SUCCEEDED ( hr) && (DOMNodeTyp == NODE_TEXT))
         {
            hr = pIXMLDOMNode->QueryInterface(IID_IXMLDOMText,
                     (void**)&pIXMLDOMText);
            SUCCEEDED(hr) ? 0 : throw hr;

            if(pIXMLDOMText)
            {
            hr = pIXMLDOMText->splitText(2, &pIXMLDOMTextTemp);
            if(SUCCEEDED(hr) && pIXMLDOMTextTemp)
            {
               hr = pIXMLDOMTextTemp->get_nodeValue(&varValue);
               if(SUCCEEDED(hr))
                  ::MessageBox(NULL, _bstr_t(varValue), _T("Notation Public ID"), MB_OK);
               pIXMLDOMTextTemp->Release();
               pIXMLDOMTextTemp = NULL;
            }
            pIXMLDOMText->Release();
            pIXMLDOMText = NULL;
         }
            pIXMLDOMNode->Release();
            pIXMLDOMNode = NULL;
            break;
         }
         pIXMLDOMNode->get_firstChild(&pIXMLDOMNodeTemp);
         pIXMLDOMNode->Release();
         pIXMLDOMNode = pIXMLDOMNodeTemp;
         pIXMLDOMNodeTemp = NULL;
      }
   }
}
catch(...)
{
   if(pIXMLDOMNodeTemp)
      pIXMLDOMNodeTemp->Release();
   if(pIXMLDOMNode)
      pIXMLDOMNode->Release();
   if(pIXMLDOMTextTemp)
      pIXMLDOMTextTemp->Release();
   if(pIXMLDOMText)
      pIXMLDOMText->Release();
   if(pIXMLDOMElement)
      pIXMLDOMElement->Release();
   DisplayErrorToUser();
}
// Release pIXMLDOMDocument when finished with it.

Remarks

If you specify an offset of zero, the first text node is empty and the right-hand text node contains the previous contents of the node. If you specify an offset beyond the end of the string, a new, empty right-hand text node is created.

See Also

Applies to: IXMLDOMCDATASection | IXMLDOMText


substringData Method

Retrieves a substring of the full string from the specified range.

[Script]

Script Syntax

strValue = oXMLDOMCharacterData.substringData(offset, count);

Parameters

offset
A long integer value indicating the offset, in characters, from the beginning of the string. An offset of zero indicates copying from the start of the data.
count
A long integer value indicating the number of characters to retrieve from the specified offset.

Return Value

A string. Returns the substring.

Example

The following script example creates an IXMLDOMComment object (comment), and then uses the substringData method to retrieve the first five characters of the object.

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
var comment;
var MyStr;
xmlDoc.async = false;
xmlDoc.load("books.xml");
comment = xmlDoc.createComment("Hello World!");
MyStr = comment.substringData(0, 5);
alert(MyStr);
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMCharacterData.substringData(offset, count)

Parameters

offset
A long integer value indicating the offset, in characters, from the beginning of the string. An offset of zero indicates copying from the start of the data.
count
A long integer value indicating the number of characters to retrieve from the specified offset.

Return Value

A string. Returns the substring.

Example

The following Microsoft® Visual Basic® example creates an IXMLDOMComment object (comment), and then uses the substringData method to retrieve the first five characters of the object.

Dim xmlDoc As New Msxml2.DOMDocument
Dim comment As IXMLDOMComment
Dim MyStr As String
xmlDoc.async = False
xmlDoc.Load ("books.xml")
Set comment = xmlDoc.createComment("Hello World!")
MyStr = comment.substringData(0, 5)
MsgBox MyStr
[C/C++]

C/C++ Syntax

HRESULT substringData(
    long offset,
    long count,
    BSTR *data);

Parameters

offset [in]
The offset, in characters, from the beginning of the string. An offset of zero indicates copying from the start of the data.
count [in]
The number of characters to retrieve from the specified offset.
data [out, retval]
The substring to return.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value when returning Null.

Remarks

If the offset and count parameters indicate a range beyond the end of the string, the returned substring continues only until the end of the string data.

See Also

Applies to: IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | IXMLDOMText


transform Method

Starts the transformation process or resumes a previously failed transformation.

[Script]

Script Syntax

boolValue = objXSLProcessor.transform();

Example

var xslt = new ActiveXObject("Msxml2.XSLTemplate");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
var xslProc;
xslDoc.async = false;
xslDoc.load("sample2.xsl");
xslt.stylesheet = xslDoc;
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.load("books.xml");
xslProc = xslt.createProcessor();
xslProc.input = xmlDoc;
xslProc.transform();
alert(xslProc.output);

File Name: Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[Visual Basic]

Visual Basic Syntax

boolValue = objXSLProcessor.transform

Example

Dim xslt As New Msxml2.XSLTemplate
Dim xslDoc As New Msxml2.FreeThreadedDOMDocument
Dim xmlDoc As New Msxml2.DOMDocument
Dim xslProc As IXSLProcessor
xslDoc.async = False
xslDoc.Load "sample2.xsl"
Set xslt.stylesheet = xslDoc
xmlDoc.async = False
xmlDoc.Load "books.xml"
Set xslProc = xslt.createProcessor()
xslProc.input = xmlDoc
xslProc.Transform
MsgBox xslProc.output

File Name: Sample2.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
   <xsl:param name="param1"/>
  <xsl:template match="/">
      Hello
  </xsl:template>
  <xsl:template match="/" mode="edit">
      In Edit Mode
  </xsl:template>
  <xsl:template match="/" mode="view">
      In View Mode
  </xsl:template>
</xsl:stylesheet>
[C/C++]

C/C++ Syntax

HRESULT transform (VARIANT_BOOL* pDone);

Parameters

pDone [out, retval]
The returned success message.

C/C++ Return Values

E_FAIL
The value returned if readyState is not READYSTATE_LOADED or READYSTATE_COMPLETE, or if a transformation error is encountered, for example, a script engine error.
VARIANT_FALSE
The value returned if the end of the input tree is reached and more input is pending.
VARIANT_TRUE
The value returned if the entire transformation is completed successfully.

Remarks

When the end of the transformation is reached successfully, VARIANT_TRUE is returned.

See Also

Applies to: IXSLProcessor


transformNode Method

Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation.

[Script]

Script Syntax

strValue = oXMLDOMNode.transformNode(objStylesheet);

Parameters

objstylesheet
An object. A valid XML document or DOM node that consists of XSLT elements that direct the transformation of this node.

Return Value

A string. Returns a string that contains the product of the transformation of this XML document based on the XSLT style sheet.

Example

The following Microsoft® JScript® example fills an HTML DIV tag with the result of transformNode.

<SCRIPT>
  // Load data.
  var source = new ActiveXObject("Msxml2.DOMDocument");
  source.async = false;
  source.load("books.xml");

  // Load style sheet.
  var stylesheet = new ActiveXObject("Msxml2.DOMDocument");
  stylesheet.async = false
  stylesheet.load("sample.xsl");

  // Fill a div tag with the result of the transform
  divInfo.innerHTML = source.transformNode(stylesheet);
</SCRIPT>
[Visual Basic]

Visual Basic Syntax

strValue = oXMLDOMNode.transformNode(objStylesheet)

Parameters

objstylesheet
An object. A valid XML document or DOM node that consists of XSLT elements that direct the transformation of this node.

Return Value

A string. Returns a string that contains the product of the transformation of this XML document based on the XSLT style sheet.

Example

The following Microsoft® Visual Basic® example displays the result of transformNode.

Dim source As New Msxml2.DOMDocument
Dim stylesheet As New Msxml2.DOMDocument

' Load data.
source.async = False
source.Load "books.xml"

' Load style sheet.
stylesheet.async = False
stylesheet.Load "sample.xsl"

' Do the transform
MsgBox source.transformNode(stylesheet)
[C/C++]

C/C++ Syntax

HRESULT transformNode(
    IXMLDOMNode *stylesheet,
    BSTR *xmlString);

Parameters

stylesheet [in]
A valid XML document or DOM node that consists of XSLT elements that direct the transformation of this node.
xmlString [out, retval]
A string that contains the product of the transformation of this XML document based on the XSLT style sheet.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if stylesheet or xmlString is Null.

Remarks

The stylesheet parameter must be either a DOMDocument node, in which case the document is assumed to be an Extensible Stylesheet Language (XSL) style sheet, or a Document Object Model (DOM) node in the XSL style sheet, in which case this node is treated as a standalone style sheet fragment.

The source node defines a context in which the style sheet operates, but navigation outside this scope is allowed. For example, a style sheet can use the id function to access other parts of the document.

This method supports both standalone and embedded style sheets and also provides the ability to run a localized style sheet fragment against a particular source node.

This member is an extension of the Worldwide Web Consortium (W3C) DOM.

For more information about XSLT style sheets, see the XSLT Reference.

See Also

Using XSLT from the DOM | id Function

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


transformNodeToObject Method

Processes this node and its children using the supplied XSL Transformations (XSLT) style sheet and returns the resulting transformation in the supplied object.

[Script]

Script Syntax

oXMLDOMNode.transformNodeToObject(stylesheet, outputObject);

Parameters

stylesheet
An object. A valid XML document or DOM node that consists of XSLT elements that direct the transformation of this node.
outputObject
An object. On return, contains the product of the transformation of this XML document based on the XSLT style sheet. If the variant represents the DOMDocument object, the document is built according to its properties and its child nodes are replaced during this transformation process. The XML transformation can also be sent to a stream.

Example

The following Microsoft® JScript® example sets up the new XML document object named "result" before making the call to transformNodeToObject.

<SCRIPT>
  // Load data.
  var source = new ActiveXObject("Msxml2.DOMDocument");
  source.async = false;
  source.load("data.xml");

  // Load style sheet.
  var stylesheet = new ActiveXObject("Msxml2.DOMDocument");
  stylesheet.async = false;
  stylesheet.load("style.xsl");

  // Set up the resulting document.
  var result = new ActiveXObject("Msxml2.DOMDocument");
  result.async = false;
  result.validateOnParse = true;

  // Parse results into a result DOM Document.
  source.transformNodeToObject(stylesheet, result);
</SCRIPT>
[Visual Basic]

Visual Basic Syntax

oXMLDOMNode.transformNodeToObject(stylesheet, outputObject)

Parameters

stylesheet
An object. A valid XML document or DOM node that consists of XSLT elements that direct the transformation of this node.
outputObject
An object. On return, contains the product of the transformation of this XML document based on the XSLT style sheet. If the variant represents the DOMDocument object, the document is built according to its properties and its child nodes are replaced during this transformation process. The XML transformation can also be sent to a stream.

Example

The following Microsoft Visual Basic® example demonstrates the application of multiple style sheets to an XML file in succession.

  Dim Source As New Msxml2.DOMDocument
  Dim stylesheet As New Msxml2.DOMDocument
  Dim stylesheet2 As New Msxml2.DOMDocument
  Dim result As New Msxml2.DOMDocument
  Dim result2 As New Msxml2.DOMDocument

  ' Load data.
  Source.async = False
  Source.Load "sample.xml"

  ' Load style sheet.
  stylesheet.async = False
  stylesheet.Load "stylesheet1.xsl"

  ' Set up the resulting document.
  result.async = False
  result.validateOnParse = True
  result2.async = False
  result2.validateOnParse = True

  ' Parse results into a result DOM Document.
  Source.transformNodeToObject stylesheet, result

  stylesheet2.async = False
  stylesheet2.Load "stylesheet2.xsl"

  result.transformNodeToObject stylesheet2, result2
  MsgBox result2.xml

File Name: Sample.xml

<?xml version="1.0"?>
<COLLECTION dateCreated="01-04-2000">
 <BOOK>
    <TITLE>Home Town</TITLE>
    <AUTHOR>Tracy Kidder</AUTHOR>
    <PUBLISHER>Random House</PUBLISHER>
    <PRICE>250</PRICE>
 </BOOK>
  <BOOK>
    <TITLE>Cosmos</TITLE>
    <AUTHOR>Carl Sagan</AUTHOR>
    <PUBLISHER>Ballantine Books</PUBLISHER>
    <PRICE>200</PRICE>
 </BOOK>
 <BOOK>
    <TITLE>Catwings</TITLE>
    <AUTHOR>Ursula K. Le Guin</AUTHOR>
    <PUBLISHER>Scholastic</PUBLISHER>
    <PRICE>100</PRICE>
 </BOOK>
</COLLECTION>

Stylesheet1.xsl

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
   <PriceList>
      <xsl:for-each select="COLLECTION/BOOK">
   <xsl:sort select="TITLE" data-type="text"/>
   <xsl:copy>
   <xsl:apply-templates select="*"/>
   </xsl:copy>
      </xsl:for-each>
   </PriceList>
  </xsl:template>

  <xsl:template match="*">
   <xsl:copy>
   <xsl:apply-templates />
   </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Stylesheet2.xsl

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
   <LowPriceBooks>
      <xsl:for-each select="*/BOOK[not(PRICE >'220')]">
   <xsl:copy>
   <xsl:apply-templates select="*"/>
   </xsl:copy>
      </xsl:for-each>
   </LowPriceBooks>
  </xsl:template>
  <xsl:template match="*">
   <xsl:copy>
   <xsl:apply-templates />
   </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Final Output

<?xml version="1.0"?>
<LowPriceBooks><BOOK>
<TITLE>Catwings</TITLE>
<AUTHOR>Ursula K. Le Guin</AUTHOR><PUBLISHER>Scholastic</PUBLISHER>
<PRICE>100</PRICE></BOOK><BOOK><TITLE>Cosmos</TITLE>
<AUTHOR>Carl Sagan</AUTHOR>
<PUBLISHER>Ballantine Books</PUBLISHER><PRICE>200</PRICE>
</BOOK></LowPriceBooks>
[C/C++]

C/C++ Syntax

HRESULT transformNodeToObject(
    IXMLDOMNode *stylesheet,
    VARIANT outputObject);

Parameters

stylesheet [in]
A valid XML document or DOM node that consists of XSL elements that direct the transformation of this node.
outputObject [in]
An object that contains the product of the transformation of this XML document based on the XSLT style sheet. If the variant represents DOMDocument, the document is built according to its properties and its child nodes are replaced during this transformation process. If the variant contains an IStream interface, the XML transformation is sent to this stream.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if stylesheet or outputObject is Null.

Example

This example sets up the new DOMDocument object and puts it into a VARIANT before making the call to transformNodeToObject.

// p is the XML source that is to be transformed, pXSL is the style sheet.
// Create an empty DOM document for the result. (Error checking omitted
// for brevity.)
hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
    IID_IXMLDOMDocument, (void**)&pDoc);
hr = pDoc->QueryInterface(IID_IDispatch, (void **)&pDisp);
vObject.vt = VT_DISPATCH;   // the new object
vObject.pdispVal = pDisp;
hr = p->transformNodeToObject(pXSL, vObject);   // Transformation is
                                                // present in pDoc.

Remarks

The stylesheet parameter must be either a DOMDocument node, in which case the document is assumed to be an XSLT style sheet, or a DOM node in the XSLT style sheet, in which case this node is treated as a standalone style sheet fragment.

The source node defines a context in which the style sheet operates, but navigation outside this scope is allowed. For example, a style sheet can use the id function to access other parts of the document.

This method supports both standalone and embedded style sheets and also provides the ability to run a localized style sheet fragment against a particular source node.

The transformNodeToObject method always generates a Unicode byte-order mark, which means it cannot be used in conjunction with other Active Server Pages (ASP) Response.Write or Response.BinaryWrite calls.

For more information about XSLT, see the XSLT Reference.

This member is an extension of the Worldwide Web Consortium (W3C) DOM.

See Also

Using XSLT from the DOM | id Function

Applies to: IXMLDOMAttribute | IXMLDOMCDATASection | IXMLDOMCharacterData | IXMLDOMComment | DOMDocument | IXMLDOMDocumentFragment | IXMLDOMDocumentType | IXMLDOMElement | IXMLDOMEntity | IXMLDOMEntityReference | IXMLDOMNode | IXMLDOMNotation | IXMLDOMProcessingInstruction | IXMLDOMText | IXTLRuntime


uniqueID Method

Returns the unique identifier for the supplied node.

[Script]

Script Syntax

lValue = oXTLRuntime.uniqueID(pNode);

Parameters

pNode
An object. The node for which the unique identifier is to be returned.

Return Value

A long integer. Returns the unique identifier for the specified node.

[Visual Basic]

Visual Basic Syntax

lValue = oXTLRuntime.uniqueID(pNode)

Parameters

pNode
An object. The node for which the unique identifier is to be returned.

Return Value

A long integer. Returns the unique identifier for the specified node.

[C/C++]

C/C++ Syntax

HRESULT uniqueID(IXMLDOMNode* pNode, long* pID);

Parameters

pNode [in]
The node for which the unique identifier is to be returned.
pID [out, retval]
The unique identifier for the specified node.

C/C++ Return Values

S_OK
The value returned if successful.

See Also

Applies to: IXTLRuntime


validate Method

Performs run-time validation on the currently loaded document using the currently loaded document type definition (DTD), schema, or schema collection.

[Script]

Script Syntax

objXMLDOMDocument2.validate();

Return Value

A ParseError object indicating exactly what error occurred, if any.

Example

The following Microsoft® JScript® example shows how to validate at runtime.

var xmldoc = new ActiveXObject("Msxml2.DOMDocument");
xmldoc.async = false
// This will validate on load because validateOnParse is set to true
// by default.
xmldoc.load("http://server/myData.xml");
// You make a change to an attribute:
xmldoc.documentElement.setAttribute("a", "123");
// Now you want to verify your document is still valid:
var err = xmldoc.validate();
if (err.errorCode == 0)
{
   alert("Document is valid");
}
else
{
   alert("Validation error:" + err.reason);
}
[Visual Basic]

Visual Basic Syntax

objXMLDOMDocument2.validate

Return Value

A ParseError object indicating exactly what error occurred, if any.

[C/C++]

C/C++ Syntax

HRESULT validate(IXMLDOMParseError ** errorObj);

C/C++ Return Values

An IErrorInfo containing a formatted error message indicating what went wrong and one of the following HRESULTs (also returned in the ErrorInfo.Number property).

Return value | Hexadecimal value | Description
E_PENDING | 0x8000000A | Document readyState is not 4, indicating the document is not completely loaded.
S_OK | 0 | The document is valid according to DTD or schemas.
S_FALSE | 1 | The document is invalid according to DTD or schemas. For error information, see the returned IXMLDOMParseError object.

The following possible validation errors returned with S_FALSE are listed, together with the errorCode value.

Message ID | Error Code (Hex Value) | Message
XML_E_NODTD | 0xC00CE224 | Validate failed because a DTD or schema was not specified in the document.
XML_E_NOTWF | 0xC00CE223 | Validate failed because the document does not contain exactly one root node.
XML_ENTITY_UNDEFINED | 0xC00CE002 | Reference to undefined entity '%1'.
XML_INFINITE_ENTITY_LOOP | 0xC00CE003 | Entity '%1' contains an infinite entity reference loop.
XML_NDATA_INVALID_PE | 0xC00CE004 | Cannot use the NDATA keyword in a parameter entity declaration.
XML_REQUIRED_NDATA | 0xC00CE005 | Cannot use a general parsed entity '%1' as the value for attribute '%2'.
XML_NDATA_INVALID_REF | 0xC00CE006 | Cannot use unparsed entity '%1' in an entity reference.
XML_EXTENT_IN_ATTR | 0xC00CE007 | Cannot reference an external general parsed entity '%1' in an attribute value.
XML_ELEMENT_UNDECLARED | 0xC00CE00D | The element '%1' is used but not declared in the DTD or schema.
XML_ELEMENT_ID_NOT_FOUND | 0xC00CE00E | The attribute '%1' references the ID '%2', which is not defined in the document.
XML_EMPTY_NOT_ALLOWED | 0xC00CE011 | Element cannot be empty according to the DTD or schema.
XML_ELEMENT_NOT_COMPLETE | 0xC00CE012 | Element content is incomplete according to the DTD or schema.
XML_ROOT_NAME_MISMATCH | 0xC00CE013 | The name of the top-most element must match the name of the DOCTYPE declaration.
XML_INVALID_CONTENT | 0xC00CE014 | Element content is invalid according to the DTD or schema.
XML_ATTRIBUTE_NOT_DEFINED | 0xC00CE015 | The attribute '%1' on this element is not defined in the DTD or schema.
XML_ATTRIBUTE_FIXED | 0xC00CE016 | Attribute '%1' has a value that does not match the fixed value defined in the DTD or schema.
XML_ATTRIBUTE_VALUE | 0xC00CE017 | Attribute '%1' has an invalid value according to the DTD or schema.
XML_ILLEGAL_TEXT | 0xC00CE018 | Text is not allowed in this element according to DTD or schema.
XML_MULTI_FIXED_VALUES | 0xC00CE019 | An attribute declaration cannot contain multiple fixed values: '%1'.
XML_ELEMENT_UNDEFINED | 0xC00CE01C | Reference to undeclared element: '%1'.
XML_XMLNS_FIXED | 0xC00CE01E | Attribute '%1' must be a #FIXED attribute.
XML_REQUIRED_ATTRIBUTE_MISSING | 0xC00CE020 | Required attribute '%1' is missing.
XML_DTD_EXPECTING | 0xC00CE026 | Expecting: %1.
XML_E_NODTD | 0xC00CE224 | Validate failed because a DTD or schema was not specified in the document.

Remarks

This method only validates fully loaded documents (readyState == 4).

The validate method returns an IXMLDOMParseError that is independent of the value returned by the parseError property on a document. Only the errorCode and reason properties of the returned value are set.

Unlike load, validate will fail if there is no DTD or schema applied to the document element. Therefore, validate will not be able tell you whether the document is just well-formed.

The validate method does not parse new schemas, but can import a schema from a SchemaCache associated with the document through the schemas property. If there is no schema for a given namespace, the elements in that namespace will not be validated.

See Also

readyState Property | IXMLDOMParseError

Applies to: IXMLDOMDocument2


waitForResponse Method

Allows the requesting server to suspend execution while waiting for an asynchronous send operation to complete.

[Script]

Script Syntax

oServerXMLHTTPRequest.waitForResponse(timeoutInSeconds);

Parameters

timeoutInSeconds
(Optional.) Specifies the number of seconds to wait for an asynchronous send operation to complete.

Example

var xmlServerHttp = new ActiveXObject("Msxml2.ServerXMLHTTP");
xmlServerHttp.open("GET", "http://localhost/sample.xml", true);
xmlServerHttp.send();
while (xmlServerHttp.readyState != 4) {
   xmlServerHttp.waitForResponse(1000);
}
[Visual Basic]

Visual Basic Syntax

oServerXMLHTTPRequest.waitForResponse(timeoutInSeconds)

Parameters

timeoutInSeconds
(Optional.) Specifies the number of seconds to wait for an asynchronous send operation to complete.

Example

Dim xmlServerHttp As New Msxml2.ServerXMLHTTP
xmlServerHttp.open "GET", "http://localhost/sample.xml", True
xmlServerHttp.send
While xmlServerHttp.readyState <> 4
    xmlServerHttp.waitForResponse 1000
Wend
[C/C++]

C/C++ Syntax

HRESULT waitForResponse(VARIANT timeoutInSeconds, VARIANT_BOOL * isSuccessful);

Parameters

timeoutInSeconds [in]
(Optional.) Specifies the number of seconds to wait for an asynchronous send operation to complete.
isSuccessful [out, retval]
The waitForResponse method is more efficient than polling the readyState property, which is the only way to wait for an asynchronous send using the XMLHTTP component. The caller can supply an optional timeout parameter, specified in seconds. The default timeout (if one is not specified) is INFINITE (-1). The method returns True if a response is received within the time allotted, or False if a timeout occurs. If the method times out, the request is not aborted; the caller can continue to wait for the request in a subsequent call to the waitForResponse method. Calling waitForResponse after a synchronous send method returns immediately and has no useful effect. The async parameter to the open method controls whether the send is synchronous (default) or asynchronous. The results of this method are valid only after the send method has been completed successfully.

C/C++ Return Values

S_OK
The value returned if successful.

See Also

open Method | readyState Property | send Method

Applies to: IServerXMLHTTPRequest/ServerXMLHTTP


XML DOM Events

This section includes the following topics:

  • ondataavailable Event
  • onreadystatechange Event
  • ontransformnode Event


ondataavailable Event

Fires when new data is available.

Inline HTML
<ELEMENT ondataavailable = "handler" ... >
 All platforms
Event property
object.ondataavailable = handler
 Microsoft® JScript® (compatible with ECMA 262 language specification) only
Named script
<SCRIPT FOR = object EVENT = ondataavailable>
 Microsoft Internet Explorer only

[Script]

Script Syntax

oXMLDOMDocument.ondataavailable;
[Visual Basic]

Visual Basic Syntax

oXMLDOMDocument.ondataavailable
[C/C++]

C/C++Syntax

HRESULT ondataavailable(void);

C/C++ Return Values

S_OK
The value returned if successful.

Example

// Assumptions :
// The sink (an object of the class defined below) has been connected
// to the connection point (DIID_XMLDOMDocumentEvents).
// To see an example of how to connect the connection point,
// see the example for the IXMLDOMDocument::onreadystatechange Event.

BEGIN_DISPATCH_MAP(CXMLDOMSamples, CCmdTarget)
   DISP_FUNCTION_ID(CXMLDOMSamples, "Data Available Event Handler",
   DISPID_XMLDOMEVENT_ONDATAAVAILABLE, DOMDocOnDataAvailable, VT_EMPTY, 0)
END_DISPATCH_MAP()

class CXMLDOMSamples : public CCmdTarget
{
public:
   void DOMDocOnDataAvailable();
};
void CXMLDOMSamples::DOMDocOnDataAvailable()
{
   // Called whenever any data is available.
   try
   {
       ::MessageBox(NULL, _T("in ondataavailable()"), _T("Error"), MB_OK);
   }
   catch(...)
   {
      DisplayErrorToUser();
   }
}

Remarks

When handling asynchronous data, it is useful to be able to start processing in parallel with the download as soon as data becomes available. The readyState property defines several states that specify the current status of the asynchronous download.

The event handler for this event can be explicitly set using the ondataavailable property.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

ondataavailable Property | readyState Property (DOMDocument)

Applies to: DOMDocument


onreadystatechange Event

Fires when the readyState method changes.

Inline HTML
<ELEMENT onreadystatechange = "handler" ... >
 All platforms
Event property
object.onreadystatechange = handler
 Microsoft® JScript® (compatible with ECMA 262 language specification) only
Named script
<SCRIPT FOR = object EVENT = onreadystatechange>
 Microsoft Internet Explorer only

[Script]

Script Syntax

oXMLDOMDocument.onreadystatechange;
[Visual Basic]

Visual Basic Syntax

oXMLDOMDocument.onreadystatechange
[C/C++]

C/C++ Syntax

HRESULT onreadystatechange(void);

C/C++ Return Values

S_OK
The value returned if successful.
[Visual Basic]

Example

The following example shows how to use the onreadystatechange event in an application.

Dim WithEvents xmldoc As DOMDocument

Private Sub Form_Load()
    Set xmldoc = New DOMDocument
    xmldoc.Load ("http://MyServer/Sample.xml")
End Sub

Private Sub xmldoc_onreadystatechange()
    If (xmldoc.readyState = 4) Then
       msg = "Load is finished" & Chr(13)
       If (xmldoc.parseError.errorCode <> 0) Then
            msg = msg + "Error: " & xmldoc.parseError.reason
       End If
       MsgBox msg
    End If
End Sub
[C/C++]

Example

BEGIN_DISPATCH_MAP(CXMLDOMSamples, CCmdTarget)
   DISP_FUNCTION_ID(CXMLDOMSamples, "Ready State Event Handler",
   DISPID_XMLDOMEVENT_ONREADYSTATECHANGE, DOMDocCheckState, VT_EMPTY, 0)
END_DISPATCH_MAP()

class CXMLDOMSamples : public CCmdTarget
{
private:
   HRESULT m_hr;
   IXMLDOMDocument* m_pIXMLDOMDocument;
   BSTR m_bstrXMLDocName;
   DWORD m_pdwCookie;
public:
   BOOL AdviseConnectionPoint(BOOL bAdvise = TRUE);
   void Caller();
   BOOL DOMDocLoadLocation();
   BOOL DOMDocStateChangeSetup();
   void DOMDocCheckState();
};

// Assumptions
// m_pIXMLDOMDocument has already been initialized (a DOMDocument
// object has been created).
// Automation is enabled for the class to enable it to connect
// to the Connection point (DIID_XMLDOMDocumentEvents).

void CXMLDOMSamples::Caller()
{
   try
   {
   m_bstrXMLDocName = ::SysAllocString(_T("http://MyServer/sample.xml"));
   DOMDocStateChangeSetup();
   DOMDocLoadLocation();
   ::SysFreeString(m_bstrXMLDocName);
   m_bstrXMLDocName = NULL;
}
   catch(...)
   {
      if(m_bstrXMLDocName)
      ::SysFreeString(m_bstrXMLDocName);
      DisplayErrorToUser();
   }
}
BOOL CXMLDOMSamples::AdviseConnectionPoint(BOOL bAdvise)
{
   BOOL bResult = FALSE;
   try
   {
      IConnectionPointContainer *pIConnectionPointContainer = NULL;
      IConnectionPoint *pCP = NULL;

      m_hr = m_pIXMLDOMDocument->QueryInterface
      (IID_IConnectionPointContainer,(void**)&pIConnectionPointContainer);
      SUCCEEDED(m_hr) ? 0 : throw m_hr;

      If(pIConnectionPointContainer)
      {
         m_hr = pIConnectionPointContainer->FindConnectionPoint
               (DIID_XMLDOMDocumentEvents, &pCP);
         SUCCEEDED(m_hr) ? 0 : throw m_hr;
         if(SUCCEEDED(m_hr) && pCP)
         {
            if(bAdvise)
               m_hr = pCP->Advise(GetIDispatch(TRUE), &m_pdwCookie);
            else
               m_hr = pCP->Unadvise(m_pdwCookie);
            bResult = SUCCEEDED(m_hr) ? TRUE : FALSE;
            pCP->Release();
            pCP = NULL;
         }
         pIConnectionPointContainer->Release();
         pIConnectionPointContainer = NULL;
      }
   }
   catch(...)
   {
      if(pIConnectionPointContainer)
         pIConnectionPointContainer->Release();
      if(pCP)
         pCP->Release();
      DisplayErrorToUser();
   }
   return bResult;
}
BOOL CXMLDOMSamples::DOMDocStateChangeSetup()
{
   BOOL bResult = FALSE;
   try
   {
      m_hr = m_pIXMLDOMDocument->put_async(VARIANT_TRUE);
      SUCCEEDED(m_hr) ? 0 : throw m_hr;
      bResult = AdviseConnectionPoint();
   }
   catch(...)
   {
      DisplayErrorToUser();
   }
   return bResult;
}
BOOL CXMLDOMSamples::DOMDocLoadLocation()
{
   short sResult = FALSE;
   BOOL bResult = FALSE;
   try
   {
      _variant_t varString = m_bstrXMLDocName;
      m_hr = m_pIXMLDOMDocument->load(varString, &sResult);
      bResult = SUCCEEDED(m_hr) ? TRUE : FALSE;
   }
   catch(...)
   {
      DisplayErrorToUser();
   }
   return bResult;
}
void CXMLDOMSamples::DOMDocCheckState()
{
   IXMLDOMParseError *pIParseError = NULL;
   long value;

   try
   {
      m_hr = m_pIXMLDOMDocument->get_readyState(&value);
      SUCCEEDED(m_hr) ? 0 : throw m_hr;
      if(value == 4 )
      {
         m_hr = m_pIXMLDOMDocument->get_parseError(&pIParseError);
         SUCCEEDED(m_hr) ? 0 : throw m_hr;
         m_hr = pIParseError->get_errorCode(&value);
         pIParseError->Release();
         pIParseError=NULL;
         if(!SUCCEEDED(m_hr))
         {
            throw m_hr;
         }
         m_strOutput = (value != 0) ? _T("Load Error") : _T("Load
            Succeeded");
      }
   }
   catch(...)
   {
      if(pIParseError)
         pIParseError->Release();
      DisplayErrorToUser();
   }
}
[Script]

Example

The following JScript and HTML example demonstrates the sequence of ready states when asynchronously loading a document.

<script>
var xmldoc;
function Load()
{
  xmldoc = new ActiveXObject("Microsoft.XMLDOM");
  xmldoc.onreadystatechange = CheckState;
  xmldoc.load(URL.value);
}
function CheckState()
{
  var state = xmldoc.readyState;
  RESULTS.innerHTML += "readyState = " + state + "<BR>"
  if (state == 4)
  {
    var err = xmldoc.parseError;
    if (err.errorCode != 0)
      RESULTS.innerHTML += err.reason + "<BR>"
    else RESULTS.innerHTML +="success" + "<BR>"
  }
}
</script>
URL: <input type=text size=60 id=URL>
<input type=button value=LOAD onclick="jscript:Load()">
<div id=RESULTS style= "color:red;font-weight:bold;"></div>
[Visual Basic]

The following Microsoft Visual Basic® example shows how to use the onreadystatechange event in an application.

Dim WithEvents xmldoc As DOMDocument

Private Sub Form_Load()
    Set xmldoc = New DOMDocument
    xmldoc.Load ("http://MyServer/Sample.xml")
End Sub

Private Sub xmldoc_onreadystatechange()
    If (xmldoc.readyState = 4) Then
      msg = "Load  is finished" & Chr(13)
      If (xmldoc.parseError.errorCode <> 0) Then
        msg = msg + "Error: " & xmldoc.parseError.reason
      End If
      MsgBox msg
    End If
End Sub

Remarks

This event can be explicitly set using the onreadystatechange property.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

onreadystatechange Property (DOMDocument)

Applies to: DOMDocument


ontransformnode Event

Fires before the style sheet is applied to a node.

Important The ontransformnode event does not fire on DOMDocument for style sheets using the XLST namespace "http://www.w3.org/1999/XSL/Transform". It does, however, fire on DOMDocument for style sheets using the XSL namespace "http://www.w3.org/XSL/Transform/1.0".
[Script]

Script Syntax

boolVal = ontransformnode(nodeCode, nodeData);

Parameters

nodeCode
The indicator of the current node in the style sheet.
nodeData
The indicator of the current node in the XML source data.

Return Value

True to indicate that transformation processing is to continue; False to indicate that transformation processing should stop.

[Visual Basic]

Visual Basic Syntax

boolVal = ontransformnode(nodeCode, nodeData)

Parameters

nodeCode
The indicator of the current node in the style sheet.
nodeData
The indicator of the current node in the XML source data.

Return Value

True to indicate that transformation processing is to continue; False to indicate that transformation processing should stop.

[Script]

Example

In this example, the XML data island named "target" contains the XML source data, and the XML data island named "ss" contains the XSL Transformations (XSLT) style sheet.

<XML id="target">
  <PEOPLE>
    <PERSON name="Atkinson, Teresa"  />
    <PERSON name="Debroux, Steve" />
    <PERSON name="O'Hara, Robert" />
    <PERSON name="Porzuczek, Peter" />
  </PEOPLE>
</XML>
<XML id="ss">
  <xsl:template match="/" xmlns:xsl="http://www.w3.org/TR/WD-xsl">
    <xsl:for-each select="/PEOPLE/PERSON/@name" >
      <P><xsl:value-of /></P>
    </xsl:for-each>
  </xsl:template>
</XML>

Example

This script contains the Verify function, which sets the ontransformnode property to the event handler, onxform. The event handler is called before the transformation operation on each node so that, given the sample data provided in the data islands, this sample calls the alert several times.

<SCRIPT LANGUAGE="javascript" FOR="window" EVENT="onload">
document.expando = false;
Verify();
</SCRIPT>
<Script LANGUAGE="javascript">
function onxform ( code, doc ) {
  alert("Target document node being transformed:\n\n" + doc.xml +
    "\n\nStylesheet node used for the transform:\n\n" + code.xml);
  if (doc.value == "O'Hara, Robert")
   return false;  // Stop processing.
  else
   return true;
}
function Verify() {
  target.ontransformnode = onxform;
  var sOut = target.XMLDocument.transformNode(ss.XMLDocument);
  div.innerHTML += sOut;
}
</Script>
<DIV id="div"></DIV>
</BODY>
</HTML>

The return value from the event handler indicates whether to continue processing. In this example, the event handler checks for a particular data value and returns the value "false" to stop transformation processing.

[C/C++]

C/C++Syntax

HRESULT ontransformnode(
    IXMLDOMNode *pCode,
    IXMLDOMNode *pData,
    VARIANT vBool);

Parameters

pCode [in]
The address of the current node in the XSL style sheet.
pData [in]
The address of the current node in the XML source data.
vBool [out, retval]
Boolean. True if transformation processing is to continue; False to stop transformation processing.

C/C++ Return Values

S_OK
The value returned if successful.

Remarks

The event handler for this event can be explicitly set using the ontransformnode property.

This member is an extension of the Worldwide Web Consortium (W3C) Document Object Model (DOM).

See Also

ontransformnode Property

Applies to: DOMDocument


XML DOM Enumerated Constants

IXMLDOMNodeType enumerations specify valid settings for the Document Object Model (DOM) node type. The node type determines valid values and whether the node can have child nodes.

Values

The IXMLDOMNodeType enumeration defines the following valid values.

NODE_ELEMENT (1)
The node represents an element (its nodeTypeString property is "element"). An Element node can have the following child node types: Element, Text, Comment, ProcessingInstruction, CDATASection, and EntityReference. The Element node can be the child of the Document, DocumentFragment, EntityReference, and Element nodes.
NODE_ATTRIBUTE (2)
The node represents an attribute of an element (its nodeTypeString property is "attribute"). An Attribute node can have the following child node types: Text and EntityReference. The Attribute node does not appear as the child node of any other node type; it is not considered a child node of an Element.
NODE_TEXT (3)
The node represents the text content of a tag (its nodeTypeString property is "text"). A Text node cannot have any child nodes. The Text node can appear as the child node of the Attribute, DocumentFragment, Element, and EntityReference nodes.
NODE_CDATA_SECTION (4)
The node represents a CDATA section in the XML source (its nodeTypeString property is "cdatasection"). CDATA sections are used to escape blocks of text that would otherwise be recognized as markup. A CDATASection node cannot have any child nodes. The CDATASection node can appear as the child of the DocumentFragment, EntityReference, and Element nodes.
NODE_ENTITY_REFERENCE (5)
The node represents a reference to an entity in the XML document (its nodeTypeString property is "entityreference"). This applies to all entities, including character entity references. An EntityReference node can have the following child node types: Element, ProcessingInstruction, Comment, Text, CDATASection, and EntityReference. The EntityReference node can appear as the child of the Attribute, DocumentFragment, Element, and EntityReference nodes.
NODE_ENTITY (6)
The node represents an expanded entity (its nodeTypeString property is "entity"). An Entity node can have child nodes that represent the expanded entity (for example, Text and EntityReference nodes). The Entity node can appear as the child of the DocumentType node.
NODE_PROCESSING_INSTRUCTION (7)
The node represents a processing instruction from the XML document (its nodeTypeString property is "processinginstruction"). A ProcessingInstruction node cannot have any child nodes. The ProcessingInstruction node can appear as the child of the Document, DocumentFragment, Element, and EntityReference nodes.
NODE_COMMENT (8)
The node represents a comment in the XML document (its nodeTypeString property is "comment"). A Comment node cannot have any child nodes. The Comment node can appear as the child of the Document, DocumentFragment, Element, and EntityReference nodes.
NODE_DOCUMENT (9)
The node represents a document object, that as the root of the document tree, provides access to the entire XML document (its nodeTypeString property is "document"). It is created using the progID "Microsoft.XMLDOM" or through a data island using <XML> or <SCRIPT LANGUAGE=XML>. A Document node can have the following child node types: Element (maximum of one), ProcessingInstruction, Comment, and DocumentType. The Document node cannot appear as the child of any node types.
NODE_DOCUMENT_TYPE (10)
The node represents the document type declaration, indicated by the <!DOCTYPE> tag (its nodeTypeString property is "documenttype"). A DocumentType node can have the following child node types: Notation and Entity. The DocumentType node can appear as the child of the Document node.
NODE_DOCUMENT_FRAGMENT (11)
The node represents a document fragment (its nodeTypeString property is "documentfragment"). The DocumentFragment node associates a node or subtree with a document without actually being contained within the document. A DocumentFragment node can have the following child node types: Element, ProcessingInstruction, Comment, Text, CDATASection, and EntityReference. The DocumentFragment node cannot appear as the child of any node types.
NODE_NOTATION (12)
The node represents a notation in the document type declaration (its nodeTypeString property is "notation"). A Notation node cannot have any child nodes. The Notation node can appear as the child of the DocumentType node.

Remarks

Note that built-in and numeric entities (such as &amp;) are exposed as Text nodes rather than as Entity nodes.

See Also

IXMLDOMNode


XML Helper Objects/Interfaces

The XML Helper objects/interfaces are used with both the DOM and SAX objects and interfaces.

The following table shows the XML Helper objects/interfaces.

IMXNamespaceManager | Provides an interface for namespace management functionality.
IMXNamespacePrefixes | Provides a collection of namespace prefixes for a Microsoft® Visual Basic® implementation of IMXNamespaceManager.

Other Resources Other Resources

Web & Internet Samples


IMXNamespaceManager

[This is preliminary documentation and subject to change.]

Provides a convenient way to manage namespaces, namespace prefixes, and namespace URIs for an XML document. With IMXNamespaceManager, namespace contexts are organized as a stack of namespace declarations. Each push operation pushes a namespace declaration or set of namespace declarations onto the stack. Each pop operation discards everything from the top of the stack. Namespace declarations on the stack have both current and local context.

Current context
Set of all namespace declarations on the stack.
oNSMgr.declarePrefix( "a", "urn:same uri");
oNSMgr.pushContext();
oNSMgr.declarePrefix ("b", "urn:new uri");

The current context holds the prefixes "a" and "b".

Local context
Set of all namespace declarations from the top of the stack to the last pushContext method.
oNSMgr.declarePrefix( "a", "urn:same uri");
oNSMgr.pushContext();
oNSMgr.declarePrefix ("b", "urn:new uri");

The local context holds the prefix "b".

The following example shows how to use the IMXNamespaceManager to manage namespace declarations. Before you run the example, save the following file, test.xml, to a local drive.

test.xml

<?xml version="1.0" ?>
<x xmlns:a="http://www.example.com/a" xmlns:b="http://www.example.com/a">
   <y ref="a:firstele"/>
   <y Name="b:firstele"/>
</x>

Option Explicit
Private Sub Dictionary_AddURIs()

    Dim oNamedYs As IXMLDOMSelection
    Dim oRefYs As IXMLDOMSelection
    Dim oDomDoc As New DOMDocument40
    Dim oNSMgr As New MXNamespaceManager40
    Dim n As Variant
    Dim varName As Variant
    Dim strPrefix, strURI As String

    oDomDoc.Load "c:\test.xml"
    Set oNamedYs = oDomDoc.selectNodes("/x/y[@Name]")

Processes the nodes that have the attribute name "Name".

    For Each n In oNamedYs
        varName = n.getAttribute("Name")
        strPrefix = Left(varName, InStr(varName, ":") - 1)
        varName = Right(varName, Len(varName) - InStr(varName, ":"))

Uses the getURIFromNode method of NamespaceManager to get the URI from the declarations of the DOMDocument for the extracted prefix of the current DOM selection.

        strURI = oNSMgr.getURIFromNode(strPrefix, n)
   'User code to add a node to the dictionary
    Next

Processes the node that has the attribute name "Ref".

    Set oRefYs = oDomDoc.selectNodes("/x/y[@ref]")
        For Each n In oRefYs
        varName = n.getAttribute("ref")
        strPrefix = Left(varName, InStr(varName, ":") - 1)
        varName = Right(varName, Len(varName) - InStr(varName, ":"))

Uses the getURIFromNode method of NamespaceManager to get the URI from the declarations of the DOMDocument for the extracted prefix of the current DOM selection.

        strURI = oNSMgr.getURIFromNode(strPrefix, n)
   'User code to look up a name in the dictionary
    Next
End Sub

Remarks

IMXNamespaceManager has duplicate methods for Microsoft® Visual Basic and C++ processing, when necessary, to avoid the use of BSTR objects for C++. IMXNamespaceManager performs a search from the top of stack through all namespace declarations until a declaration is found or until the bottom of the stack is reached. Also:

For C++, all [in] BSTR parameters can be passed as null-terminated wchar_t*.

All indexes are continuous and start from 0.

IMXNamespaceManager checks [in] arguments for prefixes to ensure a valid prefix name according to the W3C Namespaces in XML Recommendation. IMXNamespaceManager does not check URI arguments.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and IDL files: msxml2.h, msxml2.idl

Version-Independent ProgID: MSXML2.MXNamespaceManager

Version-Independent CLSID: 88d969d5-f192-11d4-a65f-0040963251e5

Version-Dependent ProgID: MSXML2.MXNamespaceManager40

Version-Dependent CLSID: 88d969d6-f192-11d4-a65f-0040963251e5

Remarks

To view reference information for Visual Basic, C/C++, or Script only, click the Language Filter button Language Filter in the upper-left corner of the page.

See Also

IMXNamespaceManager Members | IMXNamespacePrefixes Interface

Other Resources Other Resources

W3C Namespaces in XML Recommendation


IMXNamespaceManager Members

Properties

allowOverride Controls whether the declarePrefix() method allows duplicate prefixes in the local context.

Methods

declarePrefix | Binds the namespace prefix with the namespace URI in the current context.
getDeclaredPrefixes | Returns a collection of declared namespace prefixes in the current context.
getPrefixes | Returns a collection of namespace prefixes bound to the specified URI.
getURI | Returns the namespace URI for the specified prefix.
getURIFromNode | Returns the namespace URI for the provided prefix in the context of a DOM node.
popContext | Pops local context from the top of the stack.
pushContext | Pushes local context down the stack.
pushNodeContext | Pushes local context down the stack while creating a new local context defined by a DOM node.
reset | Clears the stack of contexts, emptying the current context.

[C/C++]

C++ Methods

_getDeclaredPrefix | Returns the indexed prefix in the current context.
_getPrefix | Finds the indexed prefix associated with the provided URI.
_getURI | Returns the namespace URI for the provided prefix and DOM node.

Events

None.

See Also

IMXNamespaceManager | IMXNamespacePrefixes


IMXNamespacePrefixes

[This is preliminary documentation and subject to change.]

Provides a collection of namespace prefixes for the Microsoft® Visual Basic® and Script implementations of IMXNamespaceManager.

Requirements

Implementation: msxml4.dll, msxml2.lib

To view reference information for Visual Basic, C/C++, or Script only, click the Language Filter button Language Filter in the upper-left corner of the page.

See Also

IMXNamespacePrefixes Members | IMXNamespaceManager Interface


IMXNamespacePrefixes Members

Properties

item | Returns a prefix from the indicated index in the prefixes collection.
length | Length of the prefixes collection.

Methods

None.

Events

None.

See Also

IMXNamespaceManager Interface


XML Helper Methods

[This is preliminary documentation and subject to change.]

This section includes the following topics.

  • declarePrefix Method
  • popContext Method
  • pushContext Method
  • pushNodeContext
  • reset Method

Visual Basic/Script Methods

  • getDeclaredPrefixes Method
  • getPrefixes Method
  • getURI Method
  • getURIFromNode Method

C/C++ Methods

  • _getDeclaredPrefix Method
  • _getPrefix Method
  • _getURI Method


declarePrefix Method

[This is preliminary documentation and subject to change.]

Binds the namespace prefix with the namespace URI in the local context. You can set the allowOverride property to control whether duplicate prefixes are allowed in the local context.

[Script]

Script Syntax

ObjNSManager.declarePrefix(prefix, namespaceURI);

Parameters

prefix
The namespace prefix.
namespaceURI
The namespace URI.

Return Value

None.

Example

   var oNSMgr;

   try
   {
      oNSMgr = new ActiveXObject("MSXML2.MXNamespaceManager");
      oNSMgr.declarePrefix( "sample", "urn");
      oNSMgr.declarePrefix ("a", "abc");
      alert(oNSMgr.getDeclaredPrefixes.length); // 3
      alert(oNSMgr.getDeclaredPrefixes[0]); // "sample"
      alert(oNSMgr.getURI("sample")); // "urn"
      alert(oNSMgr.getPrefixes("urn")[0]); // "sample"
   } catch(e)
   {
      alert("Error \n" + e);
   }
[Visual Basic]

Visual Basic Syntax

ObjNSManager.declarePrefix(prefix, namespaceURI)

Parameters

prefix
The namespace prefix.
namespaceURI
The namespace URI.

Return Value

None.

Example

   Dim oNSMgr As New MSXML2.MXNamespaceManager
   oNSMgr.declarePrefix "sample", "urn "
   oNSMgr.declarePrefix "a", "abc"
   MsgBox oNSMgr.getDeclaredPrefixes.length ' 3
   MsgBox oNSMgr.getDeclaredPrefixes.Item(0) ' "sample"
   MsgBox oNSMgr.getPrefixes("urn:some uri").Item(0) ' "sample"
   MsgBox oNSMgr.getURI("sample") ' "urn"
[C/C++]
HRESULT declarePrefix(
    BSTR prefix,
    BSTR namespaceURI);

Parameters

prefix[in]
The namespace prefix.
namespaceURI[in]
The namespace URI.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned if the prefix already declared after last pushContext, pushNodeContext, and allowOverride property is VARIANT_TRUE (prefix is overridden).
E_FAIL
The value returned if the prefix already declared after last pushContext, pushNodeContext, and allowOverride property is VARIANT_FALSE (prefix is not overridden).
E_INVALIDARG
The value returned if the namespace URI is empty, but prefix is not; the prefix is invalid "xml" or "xmlns"; or the prefix is not an NCName (noncolon XML name) as defined by the W3C Namespaces in XML Recommendation.

Example

void SampleMXNameSpaceMgr_Prefixs()
{
   MSXML2::IMXNamespaceManagerPtr PtrIMXNamespaceManager;
   HRESULT hres;
   TCHAR Buffer[100];
   unsigned short WideCharBuffer[100];
   int BufferLength = 100;

   try
   {

   PtrIMXNamespaceManager.CreateInstance _
                          (__uuidof(MSXML2::MXNamespaceManager));
      PtrIMXNamespaceManager->declarePrefix(_T("sample"),_T("urn"));
      PtrIMXNamespaceManager->declarePrefix(_T("a"),_T("abc"));

      _itot(PtrIMXNamespaceManager->getDeclaredPrefixes()->length, _
                                                           Buffer, _
                                                     BufferLength);
      DisplayMessageToUser(Buffer);

      BufferLength = 100;
      PtrIMXNamespaceManager->_getDeclaredPrefix(2, WideCharBuffer, _
                              &BufferLength);
      DisplayMessageToUser(_bstr_t(WideCharBuffer));

      BufferLength = 100;
      PtrIMXNamespaceManager->_getPrefix(L"urn", 1, WideCharBuffer, _
                                        &BufferLength);
      DisplayMessageToUser(_bstr_t(WideCharBuffer));

      BufferLength = 100;
      hres = PtrIMXNamespaceManager->_getURI(L"sample", NULL, _
                                            WideCharBuffer, _
                                            &BufferLength);
      DisplayMessageToUser(_bstr_t(WideCharBuffer));
   }
   catch(...)
   {
      DisplayMessageToUser("Error");
   }
}

void DisplayMessageToUser(char *Msg)
{
   ::MessageBox(NULL, Msg, _T("Message"), MB_OK);
}

Remarks

The declarePrefix method replaces the previous declaration if a prefix has already been declared in the local context and allowOverride is enabled. The NamespaceURI parameter should not be empty unless it is used to redefine the default namespace with a namespace that contains an empty prefix. For example: nm.declarePrefix " "," " is permitted, but nm.declarePrefix "a"," " is not.

The invalid prefixes "xml" and "xmlns" cannot be passed to this method.

An error is raised if the prefix is invalid or the namespace URI is " " and its prefix is not " ".

See Also

allowOverride property

Applies to: IMXNamespaceManager

Other Resources Other Resources

W3C Namespaces in XML Recommendation


getDeclaredPrefixes Method

[This is preliminary documentation and subject to change.]

Returns a collection of declared namespace prefixes bound to a namespace name.

[Script]

Script Syntax

var objNSPrefixes = objNSManager.getDeclaredPrefixes();

Parameters

None.

Return Values

Object. Returns the collection of prefixes

Example

var oNSMgr;

   try
   {
      oNSMgr = new ActiveXObject("MSXML2.MXNamespaceManager");
      oNSMgr.declarePrefix( "sample", "urn");
      oNSMgr.declarePrefix ("a", "abc");
      alert(oNSMgr.getDeclaredPrefixes.length); // 3
      alert(oNSMgr.getDeclaredPrefixes[0]); // "sample"
      alert(oNSMgr.getURI("sample")); // "urn"
      alert(oNSMgr.getPrefixes("urn")[0]); // "sample"
   }catch(e)
   {
      alert("Error \n" + e);
   }

Remarks

The returned collection is never empty. If no prefixes have been declared, the returned collection contains the prefix "xml" (permanently bound to "http://www.w3.org/XML/1998/namespace").

If the URI reference in a default namespace declaration is empty, then unprefixed elements in the scope of the declaration are not considered to be in any namespace. This causes the prefix xmlns to be used only for namespace bindings and is not itself bound to any namespace name.

[Visual Basic]

Visual Basic Syntax

set objNSPrefixes = objNSManager.getDeclaredPrefixes

Parameters

None.

Return Values

An object. Returns the collection of prefixes

Example

    Dim oNSMgr As New MSXML2.MXNamespaceManager
    oNSMgr.declarePrefix "sample", "urn"
    oNSMgr.declarePrefix "a", "abc"
    MsgBox oNSMgr.getDeclaredPrefixes.length ' 3
    MsgBox oNSMgr.getDeclaredPrefixes.Item(0) ' "sample"
    MsgBox oNSMgr.getPrefixes("urn").Item(0) ' "sample"
    MsgBox oNSMgr.getURI("sample") ' "urn"

Remarks

The returned collection is never empty. If no prefixes have been declared, the returned collection contains the prefix "xml" (permanently bound to "http://www.w3.org/XML/1998/namespace"). If the URI reference in a default namespace declaration is empty, then unprefixed elements in the scope of the declaration are not considered to be in any namespace. This causes the prefix xmlns to be used only for namespace bindings and is not itself bound to any namespace name.

[C/C++]
HRESULT getDeclaredPrefixes(
    IMXNamespacePrefixes** prefixes);

Parameters

prefixes[out,retval]
The prefixes collection.

C/C++ Return Values

S_OK
The value returned if successful.
E_POINTER
The value returned if the last parameter is NULL.
E_OUTOFMEMORY
The value returned if there is no memory for IMXNamespacePrefixes.

Remarks

The returned collection is never empty. If no prefixes have been declared, the returned collection contains the prefix 'xml' (permanently bound to 'http://www.w3.org/XML/1998/namespace'). If the URI reference in a default namespace declaration is empty, then unprefixed elements in the scope of the declaration are not considered to be in any namespace. This causes the prefix xmlns to be used only for namespace bindings and is not itself bound to any namespace name.

See Also

getPrefixes Method | _getDeclaredPrefix Method (C++)

Applies to: IMXNamespaceManager


getPrefixes Method

[This is preliminary documentation and subject to change.]

Returns a collection of namespace prefixes bound to the specified URI.

[Script]

Script Syntax

var objNSPrefixCol = obnNSManager.getPrefixes(namespaceURI)

Parameters

namespaceURI
A string. The namespace URI bound to the prefix.

Return Values

Object. Return collection of prefixes.

Example

   var oNSMgr;

   try
   {
      oNSMgr = new ActiveXObject("MSXML2.MXNamespaceManager");
      oNSMgr.declarePrefix( "sample", "urn");
      oNSMgr.declarePrefix ("a", "abc");
      alert(oNSMgr.getDeclaredPrefixes.length); // 3
      alert(oNSMgr.getDeclaredPrefixes[0]); // "sample"
      alert(oNSMgr.getURI("sample")); // "urn"
      alert(oNSMgr.getPrefixes("urn")[0]); // "sample"
   } catch(e)
   {
      alert("Error \n" + e);
   }
[Visual Basic]

Visual Basic Syntax

set objNSPrefixCol = obnNSManager.getPrefixes(namespaceURI)

Parameters

strNamespaceURI
The namespace URI.

Return Values

An object. Returns a collection of prefixes.

Example

   Dim oNSMgr As New MSXML2.MXNamespaceManager
   oNSMgr.declarePrefix "sample", "urn"
   oNSMgr.declarePrefix "a", "abc"
   MsgBox oNSMgr.getDeclaredPrefixes.length ' 3
   MsgBox oNSMgr.getDeclaredPrefixes.Item(0) ' "sample"
   MsgBox oNSMgr.getPrefixes("urn").Item(0) ' "sample"
   MsgBox oNSMgr.getURI("sample") ' "urn"
[C/C++]

C/C++ Syntax

HRESULT getPrefixes(
    BSTR namespaceURI,
    IMXNamespacePrefixes** prefixes);

Parameters

namespaceURI[in]
The namespace URI.
prefixes[out, retval]
The prefixes collection.

C/C++ Return Values

S_OK
The value returned if successful.
E_POINTER
The value returned if the last parameter is NULL
E_INVALIDARG
The value returned if namespaceURI argument is an empty string. A prefix cannot be bound to an empty string.
E_OUTOFMEMORY
The value returned if there is no memory for IMXNamespacePrefixes.

Remarks

When there are no prefixes bound to the specified namespace URI, the returned collection of prefixes will contain no items.

See Also

getDeclaredPrefixes Method

Applies to: IMXNamespaceManager


getURI Method

[This is preliminary documentation and subject to change.]

Returns the namespace URI for the specified prefix.

[Script]

Script Syntax

var strURI = objNSManager.getURI(prefix);

Parameters

prefix
The prefix bound to the specified namespace URI.

Return Values

A string. The namespace URI for provided prefix.

Example

   var oNSMgr;

   try
   {
      oNSMgr = new ActiveXObject("MSXML2.MXNamespaceManager");
      oNSMgr.declarePrefix( "sample", "urn:same uri");
      alert(oNSMgr.getURI("sample")); // "urn:same uri"
      oNSMgr.pushContext();
      oNSMgr.declarePrefix ("sample", "urn:new uri");
      alert(oNSMgr.getURI("sample")); // "urn:new uri"
      oNSMgr.popContext();
      alert(oNSMgr.getURI("sample")); // "urn:same uri"
   } catch(e)
   {
      alert("Error \n" + e);
   }
[Visual Basic]

Visual Basic Syntax

strURI = objNSManager.getURI(prefix)

Parameters

prefix
The prefix bound to the specified namespace URI.

Return Values

A variant. The namespace URI for the provided prefix.

Example

   Dim oNSEarly As New MSXML2.MXNamespaceManager
   oNSEarly.declarePrefix "sample", "urn:same uri"
   MsgBox oNSEarly.getURI("sample") ' "urn:same uri"
   oNSEarly.pushContext
   oNSEarly.declarePrefix "sample", "urn:new uri"
   MsgBox oNSEarly.getURI("sample") ' "urn:new uri"
   oNSEarly.popContext

   MsgBox oNSEarly.getURI("sample") ' "urn:same uri"
   If strURI <> Null Then
      MsgBox strURI
   End If
[C/C++]

C/C++ Syntax

HRESULT getURI(
    BSTR prefix,
    VARIANT* uri);

Parameters

prefix[in]
The prefix bound to the specified namespace URI.
uri[out,retval]
The namespace URI for the provided prefix.

C/C++ Return Values

S_OK
The value returned if successful.
E_FAIL
The value returned if the prefix is not bound the current context.
E_POINTER
The value returned if the last argument is NULL.

Remarks

An error is raised if a prefix is not declared or is invalid. This method does not change the current context or stack.

The prefix "xml" is always considered declared and permanently bound to "http://www.w3.org/XML/1998/namespace".

The prefix "xmlns" is used only for namespace bindings and is not itself bound to any namespace name. For prefix "xmlns", getURI() returns S_FALSE because there is no namespace it is bound to.

In the following table, the first column shows the sequence of namespace declarations in an XML document. The second and third columns show the requesting prefixes and return values of the getURI method.

Declarations | Requesting prefixes | Returns
Start of the file |  |
 | getURI "xml" | S_OK, VT_BSTR("http//…")
 | getURI "abc" | S_FALSE, VT_NULL
 | getURI "" | S_FALSE, VT_NULL
 | getURI "xmlns" | S_FALSE, VT_NULL
 | getURI "cdf" | S_FALSE, VT_NULL
 | getDeclaredPrefixes | ("xml")
xmlns="urn://1" |  |
xmlns:abc="urn://2" |  |
 | getURI "xml" | S_OK, VT_BSTR("http//…")
 | getURI "abc" | S_OK, VT_BSTR("urn://2")
 | getURI "" | S_OK, VT_BSTR("urn://1")
 | getURI "xmlns" | S_FALSE, VT_NULL
 | getURI "cdf" | S_FALSE, VT_NULL
 | getDeclaredPrefixes | ("abc", "", "xml")
xmlns="" |  |
 | getURI "xml" | S_OK, VT_BSTR("http//…")
 | getURI "abc" | S_OK, VT_BSTR("urn://2")
 | getURI "" | S_FALSE, VT_NULL
 | getURI "xmlns" | S_FALSE, VT_NULL
 | getURI "cdf" | S_FALSE, VT_NULL
 | getDeclaredPrefixes | ("abc", "xml")

Applies to: IMXNamespaceManager


getURIFromNode Method

Returns the namespace URI for the provided prefix and DOM node.

[Script]

Script Syntax

var strURI = objNSManager.getURIFromNode(strPrefix, objIXMLDOMNode);

Parameters

strPrefix
The namespace prefix.
objIXMLDOMNode
The provided DOM node.

Return Values

A variant. The namespace URI.

[Visual Basic]

Visual Basic Syntax

strURI = objNSManager.getURIFromNode(strPrefix, objIXMLDOMNode);

Parameters

strPrefix
The namespace prefix.
objIXMLDOMNode
The provided DOM node.

Return Values

A variant. The namespace URI.

[C/C++]

C/C++ Syntax

HRESULT getURIFromNode(
    BSTR strPrefix,
    IXMLDOMNode* contextNode,
    VARIANT* uri);

Parameters

strPrefix[in]
The namespace prefix.
contextNode[in]
The provided DOM node.
uri[out,retval]
The namespace URI.

C/C++ Return Values

S_OK
The value returned if successful.
S_FALSE
The value returned if the prefix is not bound to the current context.
E_INVALIDARG
The value returned if contextNode is NULL.
E_POINTER
The value returned if the passed object or pointer to return string is NULL.

Remarks

Current context on the stack is not available for this method. The stack and current context on the stack are not affected.

To use the context of the same node several times, use a separate instance of the NamespaceManager object or reset the current one. Resetting the current instance of NamespaceManager will cause the loss of the current stack.

See Also

getURI Method

Applies to: IMXNamespaceManager


popContext Method

[This is preliminary documentation and subject to change.]

Pops the last local context from the top of the stack.

[Script]

Script Syntax

objNSManager.popContext();

Parameters

None.

Example

   var oNSMgr;

   try
   {
      oNSMgr = new ActiveXObject("MSXML2.MXNamespaceManager");
      oNSMgr.declarePrefix( "sample", "urn:same uri");
      alert(oNSMgr.getURI("sample")); // "urn:same uri"
      oNSMgr.pushContext();
      oNSMgr.declarePrefix ("sample", "urn:new uri");
      alert(oNSMgr.getURI("sample")); // "urn:new uri"
      oNSMgr.popContext();
      alert(oNSMgr.getURI("sample")); // "urn:same uri"
   } catch(e)
   {
      alert("Error \n" + e);
   }
[Visual Basic]

Visual Basic Syntax

objNSManager.popContext

Parameters

None.

Example

   Dim oNSMgr As New MSXML2.MXNamespaceManager
   oNSMgr.declarePrefix "sample", "urn:same uri"
   MsgBox oNSMgr.getURI("sample") ' "urn:same uri"
   oNSMgr.pushContext
   oNSMgr.declarePrefix "sample", "urn:new uri"
   MsgBox oNSMgr.getURI("sample") ' "urn:new uri"
   oNSMgr.popContext
      MsgBox oNSMgr.getURI("sample") ' "urn"same uri"
[C/C++]

C/C++ Syntax

HRESULT popContext();

Parameters

None.

C/C++ Return Values

S_OK
The value returned if successful.
E_FAIL
The value returned if no context is available to pop.

Example

   MSXML2::IMXNamespaceManagerPtr PtrIMXNamespaceManager;
   HRESULT hres;
   unsigned short WideCharBuffer[100];
   int BufferLength = 100;

   try
   {
      PtrIMXNamespaceManager.CreateInstance _
                             (__uuidof(MSXML2::MXNamespaceManager));
      PtrIMXNamespaceManager->declarePrefix(_T("sample"),_T("urn"));

      hres = PtrIMXNamespaceManager->_getURI(L"sample", NULL, _
                                     WideCharBuffer, &BufferLength);
      DisplayMessageToUser(_bstr_t(WideCharBuffer));

      PtrIMXNamespaceManager->pushContext();

      PtrIMXNamespaceManager->declarePrefix(_T("sample"),_T("urn2"));

      BufferLength = 100;
      hres = PtrIMXNamespaceManager->_getURI(L"sample", NULL, _
                                     WideCharBuffer, &BufferLength);
      DisplayMessageToUser(_bstr_t(WideCharBuffer));

      PtrIMXNamespaceManager->popContext();

      BufferLength = 100;
      hres = PtrIMXNamespaceManager->_getURI(L"sample", NULL, _
                                     WideCharBuffer, &BufferLength);
      DisplayMessageToUser(_bstr_t(WideCharBuffer));
      }
   catch(...)
   {
      DisplayMessageToUser("Error");
   }
}

void DisplayMessageToUser(char *Msg)
{
   ::MessageBox(NULL, Msg, _T("Message"), MB_OK);

Remarks

Removes everything from the top of stack down to the declaration prior to the last pushContext method call. If no context is available to pop, popContext returns an error.

See Also

Applies to: IMXNamespaceManager


pushContext Method

[This is preliminary documentation and subject to change.]

Pushes the local context down the stack.

[Script]

Script Syntax

objNSManager.pushContext();

Parameters

None.

Example

var oNSMgr;

   try
   {
      oNSMgr = new ActiveXObject("MSXML2.MXNamespaceManager");
      oNSMgr.declarePrefix( "sample", "urn:same uri");
      alert(oNSMgr.getURI("sample"));
      oNSMgr.pushContext();
      oNSMgr.declarePrefix ("sample", "urn:new uri");
      alert(oNSMgr.getURI("sample"));
      oNSMgr.popContext();
      alert(oNSMgr.getURI("sample"));
   } catch(e)
   {
      alert("Error \n" + e);
   }
[Visual Basic]

Visual Basic Syntax

objNSManager.pushContext

Parameters

None.

Example

   Dim oNSMgr As New MSXML2.MXNamespaceManager
   oNSMgr.declarePrefix "sample", "urn:same uri"
   MsgBox oNSMgr.getURI("sample")
   oNSMgr.pushContext
   oNSMgr.declarePrefix "sample", "urn:new uri"
   MsgBox oNSMgr.getURI("sample")
   oNSMgr.popContext

   MsgBox oNSMgr.getURI("sample")
[C/C++]

C/C++ Syntax

HRESULT pushContext();

Parameters

None.

C/C++ Return Values

S_OK
The value returned if successful.

Example

MSXML2::IMXNamespaceManagerPtr PtrIMXNamespaceManager;
   HRESULT hres;
   unsigned short WideCharBuffer[100];
   int BufferLength = 100;

   try
   {
      PtrIMXNamespaceManager.CreateInstance( _
                              __uuidof(MSXML2::MXNamespaceManager));
      PtrIMXNamespaceManager->declarePrefix(_T("sample"),_T("urn"));

      hres = PtrIMXNamespaceManager->_getURI(L"sample", NULL, _
                                             WideCharBuffer, _
                                             &BufferLength);
      DisplayMessageToUser(_bstr_t(WideCharBuffer));

      PtrIMXNamespaceManager->pushContext();

      PtrIMXNamespaceManager->declarePrefix(_T("sample"),_T("urn2"));

      BufferLength = 100;
      hres = PtrIMXNamespaceManager->_getURI(L"sample", _
                                             NULL, _
                                             WideCharBuffer, _
                                             &BufferLength);
      DisplayMessageToUser(_bstr_t(WideCharBuffer));

      PtrIMXNamespaceManager->popContext();

      BufferLength = 100;
      hres = PtrIMXNamespaceManager->_getURI(L"sample", _
                                             NULL, _
                                             WideCharBuffer, _
                                             &BufferLength);
      DisplayMessageToUser(_bstr_t(WideCharBuffer));
   }
   catch(...)
   {
      DisplayMessageToUser("Error");
   }
}

void DisplayMessageToUser(char *Msg)
{
   ::MessageBox(NULL, Msg, _T("Message"), MB_OK);
}

Remarks

Pushes the local context to the stack while creating a new local context.

See Also

Applies to: IMXNamespaceManager


pushNodeContext Method

[This is preliminary documentation and subject to change.]

Pushes local context down the stack while creating a new local context defined by the DOM node.

[Script]

Script Syntax

var ObjNSManager.pushNodeContext(oContextNode,[fDeep as Boolean=True]);

Parameters

oContextNode
An IXMLDOMNode object. A DOM node that specifies the context to use.
fDeep
Boolean. Default is True. If True, pushes namespace declarations of parent nodes. If False, includes only namespace declarations in the provided node.
[Visual Basic]

Visual Basic Syntax

ObjNSManager.pushNodeContext(oIXMLDOMNode,[fDeep as Boolean=True]);

Parameters

oIXMLDOMNode
An IXMLDOMNode object. A DOM node that specifies the context to use.
fDeep
Boolean. Default is True. If True, pushes namespace declarations of parent nodes. If False, includes only namespace declarations in the provided node.
[C/C++]

C/C++ Syntax

HRESULT pushNodeContext(
    IXMLDONNode * oContextNode,
    VARIANT_BOOL fDeep);

Parameters

oContextNode[in]
The DOM node with context use.
fDeep[in,optional]
Boolean. Default is True. If True, pushes namespace declarations of parent nodes. If False, includes only namespace declarations in the provided node.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The value returned if the passed object is NULL.
E_FAIL
The value returned if an error occurs.

Remarks

New local context is populated with namespace declarations from the context of the DOM node. The second parameter says if deep context should be used, which includes all namespace declarations from the node and all its parents. Pushed declarations are still visible in the current context unless replaced by new declarations.

See Also

Applies to: IMXNamespaceManager


reset Method

[This is preliminary documentation and subject to change.]

Clears the stack of contexts, emptying the current context.

[Script]

Script Syntax

objNSManager.reset();

Parameters

None.

[Visual Basic]

Visual Basic Syntax

objNSManager.reset

Parameters

None.

[C/C++]

C/C++ Syntax

HRESULT reset();

Parameters

None.

C/C++ Return Values

S_OK
The value returned if successful.
E_FAIL
The value returned if an error occurs.

See Also

Applies to: IMXNamespaceManager


_getDeclaredPrefix Method (C++)

[This is preliminary documentation and subject to change.]

Returns the indexed prefix in the current context. Used for enumeration, this method requests all available prefixes in the current context. The set of prefixes begins at 0. The index value for a prefix can change as the current context changes.

C/C++ Syntax

HRESULT _getDeclaredPrefix
    [in] long nIndex,
    [in, out] wchar_t* pwchPrefix,
    [in, out] int* ppchPrefix);

Parameters

nIndex[in]
A long index value starting from 0.
pwchPrefix[in,out]
The returned prefix value. The buffer length on input contains the maximum length of the buffer.
ppchPrefix[in,out]
The length of the prefix. On output (for successful calls), the returned buffer contains the length of the prefix string. If the buffer is NULL, only the required buffer size is returned.

C/C++ Return Values

S_OK
The value returned if successful.
E_FAIL
The value returned if the index is out of bounds
E_XML_BUFFERTOOSMALL
The MSXML error code for insufficient return buffer length.
E_POINTER
The value returned if ppchPrefix is NULL.

Remarks

Returns a prefix value stored in a character buffer that is a null-terminated wide string accompanied by the length parameter. The length, ppchPrefix, parameter contains the size of the buffer on input and the length, not including the null character, of a result on output. If the pointer to the buffer is NULL, ppchPrefix contains the required buffer size.

Example

   MSXML2::IMXNamespaceManagerPtr PtrIMXNamespaceManager;
   HRESULT hres;
   TCHAR Buffer[100];
   unsigned short WideCharBuffer[100];
   int BufferLength = 100;

   try
   {
      PtrIMXNamespaceManager.CreateInstance( _
                              __uuidof(MSXML2::MXNamespaceManager));
      PtrIMXNamespaceManager->declarePrefix(_T("sample"),_T("urn"));
      PtrIMXNamespaceManager->declarePrefix(_T("a"),_T("abc"));

      _itot(PtrIMXNamespaceManager->getDeclaredPrefixes()->length, _
                                              Buffer, BufferLength);
      DisplayMessageToUser(Buffer);

      BufferLength = 100;
      PtrIMXNamespaceManager->_getDeclaredPrefix(2, WideCharBuffer, _
                              &BufferLength);
      DisplayMessageToUser(_bstr_t(WideCharBuffer));

      BufferLength = 100;
      PtrIMXNamespaceManager->_getPrefix(L"urn", 1, WideCharBuffer, _
                                         &BufferLength);
      DisplayMessageToUser(_bstr_t(WideCharBuffer));

      BufferLength = 100;
      hres = PtrIMXNamespaceManager->_getURI(L"sample", NULL, _
                                             WideCharBuffer, _
                                             &BufferLength);
      DisplayMessageToUser(_bstr_t(WideCharBuffer));
   }
   catch(...)
   {
      DisplayMessageToUser("Error");
   }
}

void DisplayMessageToUser(char *Msg)
{
    ::MessageBox(NULL, Msg, _T("Message"), MB_OK);

See Also

Applies to: IMXNamespaceManager


_getPrefix Method (C++)

[This is preliminary documentation and subject to change.]

Finds the indexed prefix associated with the provided URI. Returns the indexed prefix in the current context. Used for enumeration, this method requests all available prefixes in the current context. The set of prefixes begins at 0. Note that the index value for a prefix can change as the current context changes.

C/C++ Syntax

HRESULT _getPrefix
    [in] const wchar_t* pwszNamespaceURI,
    [in] long nIndex,
    [in, out] wchar_t* pwchPrefix,
    [in, out] int* pcchPrefix);

Parameters

pwszNamespaceURI[in]
The namespace URI associated with the prefix.
nIndex[in]
A long index value starting from 0.
pwchPrefix[in,out]
The returned prefix value. The buffer length on input contains the maximum length of the buffer. On output (for successful calls), the returned buffer contains the length of the prefix string. If the buffer is NULL, only the length is returned.
pcchPrefix[in,out]
The length of the prefix.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The URI parameter is an empty string or NULL. No prefix can be bound to an empty string.
E_FAIL
The value returned if the index is out of bounds.
E_XML_BUFFERTOOSMALL
The MSXML error code for insufficient return buffer length.
E_POINTER
The value returned if ppchPrefix is NULL.

Remarks

Return values stored in a character buffer are null-terminated wide strings that are accompanied by the length parameter. The length parameter specifies the length of the buffer on input and returns the length of the result on output. The length of the result is returned as a null-terminated string in characters. If the pointer to the buffer is NULL, the _getPrefix method returns only length.

Example

   MSXML2::IMXNamespaceManagerPtr PtrIMXNamespaceManager;
   HRESULT hres;
   TCHAR Buffer[100];
   unsigned short WideCharBuffer[100];
   int BufferLength = 100;

   try
   {
      PtrIMXNamespaceManager.CreateInstance( _
                              __uuidof(MSXML2::MXNamespaceManager));
      PtrIMXNamespaceManager->declarePrefix(_T("sample"),_T("urn"));
      PtrIMXNamespaceManager->declarePrefix(_T("a"),_T("abc"));

      _itot(PtrIMXNamespaceManager->getDeclaredPrefixes()->length, _
                                              Buffer, BufferLength);
      DisplayMessageToUser(Buffer);

      BufferLength = 100;
      PtrIMXNamespaceManager->_getDeclaredPrefix(2, WideCharBuffer, _
                              &BufferLength);
      DisplayMessageToUser(_bstr_t(WideCharBuffer));

      BufferLength = 100;
      PtrIMXNamespaceManager->_getPrefix(L"urn", 0, WideCharBuffer, _
                                         &BufferLength);
      DisplayMessageToUser(_bstr_t(WideCharBuffer));

      BufferLength = 100;
      hres = PtrIMXNamespaceManager->_getURI(L"sample", NULL, _
                                             WideCharBuffer, _
                                             &BufferLength);
      DisplayMessageToUser(_bstr_t(WideCharBuffer));
   }
   catch(...)
   {
      DisplayMessageToUser("Error");
   }
}

void DisplayMessageToUser(char *Msg)
{
    ::MessageBox(NULL, Msg, _T("Message"), MB_OK);

See Also

Applies to: IMXNamespaceManager


_getURI Method (C++)

[This is preliminary documentation and subject to change.]

Returns the namespace URI for the provided prefix in a current context or DOM node context. If DOM node is Null, it uses the current context.

C/C++ Syntax

HRESULT _getURI
    [in] const wchar_t* pwchPrefix,
    [in] IXMLDOMNode* pContextNode,
    [in, out] wchar_t* pwchUri,
    [in, out] int* pcchUri);

Parameters

pwchPrefix[in]
The prefix associated with the namespace URI.
pContextNode[in]
The provided DOM node.
pwchUri[in,out]
The returned namespace URI value. The buffer length on input contains the maximum length of the buffer. On output (for successful calls), the returned buffer contains the length of the namespace URI string. If the buffer is NULL, only the length is returned.
pcchUri[in,out]
The length of the namespace URI.

C/C++ Return Values

S_OK
The value returned if successful.
E_INVALIDARG
The URI parameter is an empty string. No prefix can be bound to an empty string.
E_FAIL
The value returned if the index is out of bounds.
E_XML_BUFFERTOOSMALL
The MSXML error code for insufficient return buffer length.
E_POINTER
The value returned if pcchURI is NULL.

Remarks

Return values stored in a character buffer are null-terminated wide strings that are accompanied by the length parameter. The length parameter specifies the length of the buffer on input and returns the length of the result on output. The length of the result is returned as a null-terminated string in characters. If the pointer to the buffer is NULL, the _getURI method returns only length.

See Also

Applies to: IMXNamespaceManager


XML Helper Properties

[This is preliminary documentation and subject to change.]

This section includes the following topics.

  • allowOverride Property
  • item Property
  • length Property


allowOverride Property

Controls whether the declarePrefix() method overwrites previously declared prefixes in the same local context.

[Script]

Script Syntax

var bolValue = objNSManager.allowOverride;
objNSManager.allowOverride = True;

Parameters

None.

Return Value

bolValue
A Boolean value. The default is True.
[Visual Basic]

Visual Basic Syntax

bolValue = objNSManager.allowOverride;
objNSManager.allowOverride = True;

Parameters

None.

Return Value

bolValue
A Boolean value. The default is True.
[C/C++]

C/C++ Syntax

HRESULT put_allowOverride(
    VARIANT_BOOL fOverride);
HRESULT get_allowOverride(
    VARIANT_BOOL* fOverride);

Parameters

fOverride[in]
Boolean.
fOverride[out,retval]
Boolean. The default is True.

C/C++ Return Values

S_OK
Always S_OK.
E_POINTER
The value returned if fOverride value is NULL.

Remarks

When namespaces are declared in XML document processing, each element will start from pushContext(NULL), and each namespace declaration will result in declarePrefix(prefix,URI). In this case, you may want to prevent the same prefix from being overridden in the same element.

See Also

item Property

Applies to: IMXNamespaceManager


item Property

Returns a prefix from the indicated index in the prefixes collection. The index begins at 0.

[Script]

Script Syntax

var strValue = objNSPrefixes.item(intIndex);

Parameters

intIndex
A long integer. Read-only. The index of the item within the prefixes collection. The index starts at 0.
[Visual Basic]

Visual Basic Syntax

strValue = objNSPrefixes.item(intIndex)

Parameters

intIndex
A long integer. Read-only. The index of the item within the prefixes collection. The index starts at 0.
[C/C++]

C/C++ Syntax

HRESULT get_item(
    long index,
    BSTR* prefix);

Parameters

index[in]
A long integer. The index of the item within the prefixes collection. The index starts at 0.
prefix[out,retval]
The return value of the prefix.

C/C++ Return Values

S_OK
The value returned if successful.
E_POINTER
The prefix value is NULL.
E_FAIL
The value returned if index value is out of bounds.

See Also

length Property

Applies to: IMXNamespacePrefixes


length Property

Returns the length of the prefixes collection. The collection starts at 0.

[Script]

Script Syntax

var intLength = objNSPrefixes.length
[Visual Basic]

Visual Basic Syntax

intLength = objNSPrefixes.length
[C/C++]

C/C++ Syntax

HRESULT get_length(
    long* length);

Parameters

length[out,retval]
The number of items in the prefix collection. The collection starts at 0.

C/C++ Return Values

S_OK
The value returned if successful.
E_POINTER
The length is NULL.

Remarks

Read-only.

See Also

item Property

Applies to: IMXNamespacePrefixes


XML Error Messages

The msxml.dll errors are generated by the parser, the Document Object Model (DOM), the Extensible Stylesheet Language (XSL) or XML Query Language (XQL) processors, or the Multipurpose Internet Mail Extension (MIME) viewer.

The following topics provide a list of error messages returned by msxml.dll.

  • IXMLParseError Error Messages
  • ServerXMLHTTP Error Messages
  • XML DOM Error Messages
  • XSLT Error Messages
  • XQL Error Messages
  • MIMETYPE Viewer Error Messages


IXMLParseError Error Messages

The errorCode property of the IXMLDOMParseError object contains the errors listed in the following table. The errorCode property is specifically for parse errors.

Parse Errors

Error Code | Description
MSG_E_FORMATINDEX_BADINDEX | The value passed in to formatIndex needs to be greater than zero.
MSG_E_FORMATINDEX_BADFORMAT | Invalid format string.
MSG_E_SYSTEM_ERROR | System error: %1.
MSG_E_MISSINGEQUALS | Missing equals sign between attribute and attribute value.
MSG_E_EXPECTED_TOKEN | Expected token %1 found %2.
MSG_E_UNEXPECTED_TOKEN | Unexpected token %1.
MSG_E_MISSINGQUOTE | A string literal was expected, but no opening quote character was found.
MSG_E_COMMENTSYNTAX | Incorrect syntax was used in a comment.
MSG_E_BADSTARTNAMECHAR | A name was started with an invalid character.
MSG_E_BADNAMECHAR | A name contained an invalid character.
MSG_E_BADCHARINSTRING | The character "<" cannot be used in an attribute value.
MSG_E_XMLDECLSYNTAX | Invalid syntax for an xml declaration.
MSG_E_BADCHARDATA | An invalid character was found in text content.
MSG_E_MISSINGWHITESPACE | Required white space was missing.
MSG_E_EXPECTINGTAGEND | The character ">" was expected.
MSG_E_BADCHARINDTD | Invalid character found in DTD.
MSG_E_BADCHARINDECL | An invalid character was found inside a DTD declaration.
MSG_E_MISSINGSEMICOLON | A semicolon character was expected.
MSG_E_BADCHARINENTREF | An invalid character was found inside an entity reference.
MSG_E_UNBALANCEDPAREN | Unbalanced parentheses.
MSG_E_EXPECTINGOPENBRACKET | An opening "[" character was expected.
MSG_E_BADENDCONDSECT | Invalid syntax in a conditional section.
MSG_E_INTERNALERROR | Internal error.
MSG_E_UNEXPECTED_WHITESPACE | White space is not allowed at this location.
MSG_E_INCOMPLETE_ENCODING | End of file reached in invalid state for current encoding.
MSG_E_BADCHARINMIXEDMODEL | Mixed content model cannot contain this character.
MSG_E_MISSING_STAR | Mixed content model must be defined as zero or more("*").
MSG_E_BADCHARINMODEL | Invalid character in content model.
MSG_E_MISSING_PAREN | Missing parenthesis.
MSG_E_BADCHARINENUMERATION | Invalid character found in ATTLIST enumeration.
MSG_E_PIDECLSYNTAX | Invalid syntax in processing instruction declaration.
MSG_E_EXPECTINGCLOSEQUOTE | A single or double closing quote character (\' or \") is missing.
MSG_E_MULTIPLE_COLONS | Multiple colons are not allowed in a name.
MSG_E_INVALID_DECIMAL | Invalid character for decimal digit.
MSG_E_INVALID_HEXADECIMAL | Invalid character for hexadecimal digit.
MSG_E_INVALID_UNICODE | Invalid Unicode character value for this platform.
MSG_E_WHITESPACEORQUESTIONMARK | Expecting white space or "?".
MSG_E_SUSPENDED | The parser is suspended.
MSG_E_STOPPED | The parser is stopped.
MSG_E_UNEXPECTEDENDTAG | End tag was not expected at this location.
MSG_E_UNCLOSEDTAG | The following tags were not closed: %1.
MSG_E_DUPLICATEATTRIBUTE | Duplicate attribute.
MSG_E_MULTIPLEROOTS | Only one top level element is allowed in an XML document.
MSG_E_INVALIDATROOTLEVEL | Invalid at the top level of the document.
MSG_E_BADXMLDECL | Invalid XML declaration.
MSG_E_MISSINGROOT | XML document must have a top level element.
MSG_E_UNEXPECTEDEOF | Unexpected end of file.
MSG_E_BADPEREFINSUBSET | Parameter entities cannot be used inside markup declarations in an internal subset.
MSG_E_PE_NESTING | The replacement text for a parameter entity must be properly nested with parenthesized groups.
MSG_E_INVALID_CDATACLOSINGTAG | The literal string "]]>" is not allowed in element content.
MSG_E_UNCLOSEDPI | Processing instruction was not closed.
MSG_E_UNCLOSEDSTARTTAG | Element was not closed.
MSG_E_UNCLOSEDENDTAG | End element was missing the character ">".
MSG_E_UNCLOSEDSTRING | A string literal was not closed.
MSG_E_UNCLOSEDCOMMENT | A comment was not closed.
MSG_E_UNCLOSEDDECL | A declaration was not closed.
MSG_E_UNCLOSEDMARKUPDECL | A markup declaration was not closed.
MSG_E_UNCLOSEDCDATA | A CDATA section was not closed.
MSG_E_BADDECLNAME | Declaration has an invalid name.
MSG_E_BADEXTERNALID | External ID is invalid.
MSG_E_BADELEMENTINDTD | An XML element is not allowed inside a DTD.
MSG_E_RESERVEDNAMESPACE | The namespace prefix is not allowed to start with the reserved string "xml".
MSG_E_EXPECTING_VERSION | The version attribute is required at this location.
MSG_E_EXPECTING_ENCODING | The encoding attribute is required at this location.
MSG_E_EXPECTING_NAME | At least one name is required at this location.
MSG_E_UNEXPECTED_ATTRIBUTE | The specified attribute was not expected at this location. The attribute may be case-sensitive.
MSG_E_ENDTAGMISMATCH | End tag %2 does not match the start tag %1.
MSG_E_INVALIDENCODING | System does not support the specified encoding.
MSG_E_INVALIDSWITCH | Switch from current encoding to specified encoding not supported.
MSG_E_EXPECTING_NDATA | NDATA keyword is missing.
MSG_E_INVALID_MODEL | Content model is invalid.
MSG_E_INVALID_TYPE | Invalid type defined in ATTLIST.
MSG_E_INVALIDXMLSPACE | XML space attribute has invalid value. Must specify "default" or "preserve".
MSG_E_MULTI_ATTR_VALUE | Multiple names found in attribute value when only one was expected.
MSG_E_INVALID_PRESENCE | Invalid ATTDEF declaration. Expected #REQUIRED, #IMPLIED, or #FIXED.
MSG_E_BADXMLCASE | The name "xml" is reserved and must be lowercase.
MSG_E_CONDSECTINSUBSET | Conditional sections are not allowed in an internal subset.
MSG_E_CDATAINVALID | CDATA is not allowed in a DTD.
MSG_E_INVALID_STANDALONE | The standalone attribute must have the value "yes" or "no".
MSG_E_UNEXPECTED_STANDALONE | The standalone attribute cannot be used in external entities.
MSG_E_DOCTYPE_IN_DTD | Cannot have a DOCTYPE declaration in a DTD.
MSG_E_MISSING_ENTITY | Reference to an undefined entity.
MSG_E_ENTITYREF_INNAME | Entity reference is resolved to an invalid name character.
MSG_E_DOCTYPE_OUTSIDE_PROLOG | Cannot have a DOCTYPE declaration outside of a prolog.
MSG_E_INVALID_VERSION | Invalid version number.
MSG_E_DTDELEMENT_OUTSIDE_DTD | Cannot have a DTD declaration outside of a DTD.
MSG_E_DUPLICATEDOCTYPE | Cannot have multiple DOCTYPE declarations.
MSG_E_RESOURCE | Error processing resource %1.
XML_IOERROR | Error opening input file: %1.
XML_ENTITY_UNDEFINED | Reference to undefined entity %1.
XML_INFINITE_ENTITY_LOOP | Entity %1 contains an infinite entity reference loop.
XML_NDATA_INVALID_PE | Cannot use the NDATA keyword in a parameter entity declaration.
XML_REQUIRED_NDATA | Cannot use a general parsed entity '%1' as the value for attribute '%2'.
XML_NDATA_INVALID_REF | Cannot use unparsed entity %1 in an entity reference.
XML_EXTENT_IN_ATTR | Cannot reference an external general parsed entity %1 in an attribute value.
XML_STOPPED_BY_USER | XML parser stopped by user.
XML_PARSING_ENTITY | Error while parsing entity %1. %2.
XML_E_MISSING_PE_ENTITY | Parameter entity must be defined before it is used.
XML_E_MIXEDCONTENT_DUP_NAME | The same name must not appear more than once in a single mixed-content declaration: %1.
XML_NAME_COLON | Entity, EntityRef, PI, Notation names, or NMToken cannot contain a colon.
XML_ELEMENT_UNDECLARED | The element %1 is used but not declared in the DTD/Schema.
XML_ELEMENT_ID_NOT_FOUND | The attribute %1 references the ID %2, which is not defined anywhere in the document.
XML_DEFAULT_ATTRIBUTE | Error in the default attribute value defined in DTD/Schema.
XML_XMLNS_RESERVED | Reserved namespace "%1" cannot be redeclared.
XML_EMPTY_NOT_ALLOWED | Element cannot be empty according to the DTD/Schema.
XML_ELEMENT_NOT_COMPLETE | Element content is incomplete according to the DTD/Schema.
XML_ROOT_NAME_MISMATCH | The name of the top-most element must match the name of the DOCTYPE declaration.
XML_INVALID_CONTENT | Element content is invalid according to the DTD/Schema.
XML_ATTRIBUTE_NOT_DEFINED | The attribute %1 on this element is not defined in the DTD/Schema.
XML_ATTRIBUTE_FIXED | Attribute %1 has a value which does not match the fixed value defined in the DTD/Schema.
XML_ATTRIBUTE_VALUE | Attribute %1 has an invalid value according to the DTD/Schema.
XML_ILLEGAL_TEXT | Text is not allowed in this element according to the DTD/Schema.
XML_MULTI_FIXED_VALUES | An attribute declaration cannot contain multiple fixed values: "%1".
XML_NOTATION_DEFINED | The notation %1 is already declared.
XML_ELEMENT_DEFINED | The element %1 is already declared.
XML_ELEMENT_UNDEFINED | Reference to undeclared element: %1.
XML_XMLNS_UNDEFINED | Reference to undeclared namespace prefix: %1.
XML_XMLNS_FIXED | Attribute %1 must be a #FIXED attribute.
XML_E_UNKNOWNERROR | Unknown error: %1.
XML_REQUIRED_ATTRIBUTE_MISSING | Required attribute %1 is missing.
XML_MISSING_NOTATION | Declaration %1 contains a reference to undefined notation %2.
XML_ATTLIST_DUPLICATED_ID | Cannot define multiple ID attributes on the same element.
XML_ATTLIST_ID_PRESENCE | An attribute of type ID must have a declared default of #IMPLIED or #REQUIRED.
XML_XMLLANG_INVALIDID | The language ID %1 is invalid.
XML_PUBLICID_INVALID | The public ID %1 is invalid.
XML_DTD_EXPECTING | Expecting: %1.
XML_NAMESPACE_URI_EMPTY | Only a default namespace can have an empty URI.
XML_LOAD_EXTERNALENTITY | Could not load %1.
XML_BAD_ENCODING | Unable to save character to %1 encoding.
SCHEMA_ATTRIBUTEVALUE_NOSUPPORT | A namespace was found but not supported at the current location.
SCHEMA_SCHEMAROOT_EXPECTED | Incorrect definition for the root element in the schema.
SCHEMA_ELEMENT_NOSUPPORT | Element %1 is not allowed in this context.
SCHEMA_ETNAME_MISSING | An ElementType declaration must contain a name attribute.
SCHEMA_ETYPE_MISSING | An element declaration must contain a type attribute.
SCHEMA_ETORDER_UNKNOWN | Schema only supports order types "seq", "one", and "many".
SCHEMA_ELEMENTDT_NOSUPPORT | Content must be "textOnly" when using datatype on an ElementType.
SCHEMA_ETORDER_DISABLED | Order must be "many" when content is "mixed".
SCHEMA_ETCONTENT_UNKNOWN | Content must be of type "empty","eltOnly","textOnly", or "mixed".
SCHEMA_ETMODEL_UNKNOWN | The value of the model must be either "open" or "closed".
SCHEMA_ELEMENT_DISABLED | Cannot contain child elements because content is set to "textOnly".
SCHEMA_ELEMENT_MISSING | Must provide at least one "element" in a group.
SCHEMA_ATTRIBUTE_NOTSUPPORT | The attribute %1 on an %2 is not supported.
SCHEMA_ATNAME_MISSING | AttributeType declaration must contain a name attribute.
SCHEMA_ATNAME_DUPLICATED | Duplicated attribute declaration.
SCHEMA_ATREQUIRED_INVALID | Invalid value for required attribute.
SCHEMA_DTTYPE_UNKNOWN | Unknown attribute datatype.
SCHEMA_DTTYPE_DUPLICATED | Duplicated datatype declaration.
SCHEMA_ENUMERATION_MISSING | An element with a values attribute must contain a type attribute of the value "enumeration".
SCHEMA_DTVALUES_MISSING | Must provide a values attribute on an element that contains a type attribute of the value "enumeration".
SCHEMA_ATYPE_MISSING | Attribute declaration must contain a type attribute.
SCHEMA_ATYPE_UNDECLARED | The specified attribute must first be declared using an AttributeType declaration.
SCHEMA_GROUP_DISABLED | A "group" is not allowed within an ElementType that has a "textOnly" content model.
SCHEMA_GMATTRIBUTE_NOTSUPPORT | The attribute %1 on a group is not supported.
SCHEMA_DTVALUES_VALUES_MISSING | The values for enumeration type are missing.
SCHEMA_ATTRIBUTE_DEFAULTVALUE | The default value "%1" is invalid.
SCHEMA_DTTYPE_DISABLED | Datatype is not allowed when content model is not "textOnly".
SCHEMA_ELEMENT_EMPTY | Child element is not allowed when content model is "empty".
SCHEMA_ELEMENT_DATATYPE | Child element is not allowed when datatype is set.
SCHEMA_DTTYPE_MISSING | Type is missing on the datatype element.
SCHEMA_MINOCCURS_INVALIDVALUE | The value of attribute minOccurs should be "0" or "1".
SCHEMA_MAXOCCURS_INVALIDVALUE | The value of attribute maxOccurs should be "1" or "*".
SCHEMA_MAXOCCURS_MUSTBESTAR | The value of attribute maxOccurs must be "*" when attribute "order" is set to "many".
SCHEMA_ELEMENTDT_EMPTY | The value of the datatype attribute cannot be empty.
SCHEMA_DOCTYPE_INVALID | DOCTYPE is not allowed in Schema.


ServerXMLHTTP Error Messages

The ServerXMLHTTP object raises the errors listed in the following table. Typically, these errors occur when calling the IServerXMLHTTPRequest::Send method.

ServerXMLHTTP Errors

Error Code | Description
0x80004005 | Unspecified error.
0x8000FFFF | Unexpected error.
0x80070008 | Out of memory.
0x8007000E | Out of memory.
0x80072ee1 | Cannot create any more ServerXMLHTTP objects (cannot exceed 5460 concurrent objects per process).
0x80072ee2 | The operation timed out.
0x80072ee4 | Internal error.
0x80072ee5 | The URL is invalid.
0x80072ee7 | The server name or address could not be resolved.
0x80072eee | Incorrect password.
0x80072eef | Authentication failure (credentials not accepted)
0x80072efd | A connection with the server could not be established
0x80072efe | Connection aborted.
0x80072eff | Connection reset.
0x80072f05 | The date in the certificate is invalid or has expired.
0x80072f06 | The host name in the certificate is invalid or does not match.
0x80072f07 | A redirect request will change a non-secure to a secure connection.
0x80072f08 | A redirect request will change a secure to a non-secure connection.
0x80072f0c | A certificate is required to complete client authentication.
0x80072f0d | The certificate authority is invalid or incorrect.
0x80072f0e | Client authentication has not been correctly installed.
0x80072f76 | The requested header was not found.
0x80072f78 | The server returned an invalid or unrecognized response.
0x80072f7a | The request for a HTTP header is invalid.
0x80072f7c | The HTTP redirect request failed.
0x80072f7d | An error occurred in the secure channel support.
0x80072f80 | The HTTP request was not redirected.
0x80072f82 | A cookie from the server has been declined acceptance.
0x80072f88 | The HTTP redirect request must be confirmed by the user.
0x80072f89 | The server certificate was invalid.


XML DOM Error Messages

The XML Document Object Model (DOM) generates the errors listed in the following table.

DOM Errors

Error Code | Description
XMLOM_DUPLICATE_ID | The ID %1 is duplicated.
XMLOM_DATATYPE_PARSE_ERROR | Error parsing %1 as %2 datatype.
XMLOM_NAMESPACE_CONFLICT | There was a namespace conflict for the "%1" namespace.
XMLOM_OBJECT_EXPAND_NOTIMPL | Unable to expand an attribute with "object" value.
XMLOM_DTDT_DUP | Cannot have two datatype attributes on one element.
XMLOM_INSERTPOS_NOTFOUND | Insert position node not found.
XMLOM_NODE_NOTFOUND | Node not found.
XMLOM_INVALIDTYPE | This operation cannot be performed with a node of type %1.
XMLOM_INVALID_XMLDECL_ATTR | %1 is not a valid attribute on the XML declaration. Only version, encoding, or standalone attributes are allowed.
XMLOM_INVALID_INSERT_PARENT | Inserting a node or its ancestor under itself is not allowed.
XMLOM_INVALID_INSERT_POS | Insert position node must be a child of the node to insert under.
XMLOM_NO_ATTRIBUTES | Attributes are not allowed on nodes of type %1.
XMLOM_NOTCHILD | The parameter node is not a child of this ode.
XMLOM_CREATENODE_NEEDNAME | createNode requires a name for given nodeType.
XMLOM_UNEXPECTED_NS | Unexpected namespace parameter.
XMLOM_MISSING_PARAM | Required parameter is missing (or null/empty).
XMLOM_INVALID_NAMESPACENODE | Namespace node is invalid.
XMLOM_READONLY | Attempt to modify a read-only node.
XMLOM_ACCESSDENIED | Access denied.
XMLOM_ATTRMOVE | Attributes must be removed before adding them to a different node.
XMLOM_BADVALUE | Invalid data for a node of type %1.
XMLOM_USERABORT | Operation aborted by caller.
XMLOM_NEXTNODEABORT | Unable to recover node list iterator position.
XMLOM_INVALID_INDEX | The offset must be zero or a positive number that is not greater than the number of characters in the data.
XMLOM_INVALID_ATTR | The provided node is not a specified attribute on this node.
XMLOM_INVALID_ONDOCTYPE | This operation cannot be performed on a DOCTYPE node.
XMLOM_INVALID_MODEL | Cannot mix different threading models in the document.
XMLOM_INVALID_DATATYPE | Datatype %1 is not supported.


XSLT Error Messages

The Extensible Stylesheet Language Transformations (XSLT) processor returns the errors listed in the following table.

XSLT Errors

Error Code | Description
XSL_PROCESSOR_STACKOVERFLOW | The XSLT processor stack has overflowed — probable cause is infinite template recursion.
XSL_PROCESSOR_UNEXPECTEDKEYWORD | Keyword %1 may not be used here.
XSL_PROCESSOR_BADROOTELEMENT | The root element of XSLT stylesheet must be <xsl:document> or <xsl:template>.
XSL_PROCESSOR_KEYWORDMAYNOTFOLLOW | Keyword %1 may not follow %2.
XSL_PROCESSOR_INVALIDSCRIPTENGINE | %1 is not a scripting language.
XSL_PROCESSOR_SCRIPTERROR_LINE | line = %1, col = %2 (line is offset from the <xsl:script> tag).
XSL_PROCESSOR_METHODERROR | Error returned from property or method call.
XSL_KEYWORD_MAYNOTCONTAIN | Keyword %1 may not contain %2.


XQL Error Messages

The XML Query Language (XQL) processor returns the errors listed in the following table.

XQL Errors

Error Code | Description
XQL_EXPR_NOT_DOM_NODE | Expression does not return a DOM node.
XQL_EXPR_NOT_QUERY_OR_INTEGER | Expression must be a query or an integer constant.
XQL_INCOMPLETE_QUERY | Incomplete query expression.
XQL_UNKNOWN_METHOD | Unknown method.
XQL_UNEXPECTED_CHAR | Unexpected character in query string.
XQL_QUERY_INVALID_HERE | %1 may not appear to the right of / or // or be used with |.
XQL_EXPR_NOT_STRING | Expression must be a string constant.
XQL_METHOD_NOT_SUPPORTED | Object does not support this method.
XQL_INVALID_CAST | Expression can't be cast to this data type.
XMLISLANDS_NOSCRIPTLETS | The XML script engine does not support script fragments. This error was probably caused by having a script tag with the language attribute set to "XML" or the text attribute set to "text/xml" before any other script tag on the page.
XQL_EXPR_NOT_QUERY_OR_STRING | Parameter must be a query or a string constant.
XQL_EXPR_NOT_INTEGER | Parameter must be an integer constant.


MIMETYPE Viewer Error Messages

The XML Multipurpose Internet Mail Extension (MIME) viewer in Microsoft® Internet Explorer 5.0 (or later) returns the errors listed in the following table.

MIMETYPE Viewer Errors

Error Code | Description
XMLMIME_ERROR | <%1TABLE width=400> <%1P style="font:13pt/15pt verdana"> The XML page cannot be displayed <%1P style="font:8pt/11pt verdana">Cannot view XML input using %3 style sheet. Please correct the error and then click the <%1a href="javascript:location.reload()" target="_self"> Refresh</%1a> button, or try again later. <%1HR><%1P style="font:bold 8pt/11pt verdana">%2</%1P><%1/TABLE> <%1pre style="font:10pt/12pt"><%1font color="blue">%4</%1font></%1pre>
XMLMIME_LINEPOS | Line %1, Position %2
XMLMIME_SOURCENA | The XML source file is unavailable for viewing.


XSLT Developer's Guide

Extensible Stylesheet Language Transformations (XSLT) is an XML-based language that enables you to transform one class of XML document to another. XSLT offers tremendous flexibility for presenting and exchanging data between disparate devices and business systems. With XSLT, you can

  • Dynamically transform XML documents into HTML documents for a variety of browsers.
  • Dynamically transform XML data into XML, HTML, or other text formats.
  • Dynamically filter information to present information targeted to a specific user or user group.

The following main sections of the XSLT Developer's Guide give you the information you need to start creating XSLT solutions.

To learn about | See
XSLT concepts, the transformation process, and setting up a development environment | Getting Started with XSLT
Viewing XML Documents in Internet Explorer, combining XML with XSLT and cascading style sheets | Displaying Transformation Results
Transforming XML data islands in HTML, using XSLT in an Active Server Pages (ASP) script, transforming as DOM, handling XSLT errors | Using XSLT from the DOM
Uses for XSLT variables and parameters, simplifying XPath expressions by using variables, passing data between XSLT files and template rules using local parameters | Using XSLT Variables and Parameters
Sorting data by numeric value and sorting on calculated variables | Sorting with XSLT
Declaring namespaces for XSLT, changing namespace prefixes programmatically using <xsl:namespace-alias> | Working with Namespaces and Prefix Aliases
Declaring the msxsl: namespace prefix, processing a tree fragment as a tree by using msxsl:node-set(), and summing sums | Using msxsl:node-set() to Process Result-Tree Fragments
Using named templates as boilerplates, passing parameters using named templates | Using Named Template Rules in XSLT
Inserting automatic numbering using position() or <xsl:number> | Inserting Automatic Numbering Using XSLT
Using <xsl:include> or <xsl:import> to insert template rules from another XSLT file, avoiding conflicting rules by using <xsl:apply-imports> | Importing and Including Style Sheets
Deciding whether to use ids or keys, using <xsl:key> and key(), grouping data using keys or generate-id() | Using XSLT Keys to Increase Performance
Graceful fallback if a given parser encounters but doesn't implement a feature from a newer version of XSLT | Forwards-Compatible Processing to Support Future Versions
ASP, debugging, data islands and client-side processing, controlling output, extension functions | Creating Interactive XSLT
Template patterns, variable patterns, class patterns, linking patterns, extension patterns, common transformations | Using Design Patterns for XSLT
Controlling white space with <xsl:text>, <xsl:preserve-space> and <xsl:strip-space>, CDATA sections, and normalize-space() | Controlling White Space with XSLT

In addition to the Microsoft® XML SDK, we recommend downloading utilities. For more information, see XSLT Utilities and Samples You Can Download.


Getting Started with XSLT

This section provides information required for creating Extensible Stylesheet Language Transformations (XSLT) solutions. In addition, this section gives you valuable background information to help you make strategic decisions about how to best use XSLT for your XML applications.

To learn about | See
The history of XSLT and a comparison of XSLT to cascading style sheets | Introduction to XSLT
The structure of an XSLT file, how the XSLT processor works, and the various types of XSLT output | Understanding the XSLT Process
How to set up your development environment to use XSLT | Setting Up XSLT
How to deploy XSLT in Microsoft® Internet Explorer or on a client or server | Deploying XSLT Solutions
How to create a simple XSLT file | Learning XSLT (A Tutorial)
Where you can find additional XSLT-related utilities, samples, and documentation | XSLT Utilities and Samples You Can Download
Solutions to common questions and concerns in working with XSLT | Frequently Asked Questions about XSLT
Mechanisms for implementing extension functions and conformance with the W3C | Supported XSLT Features

See Also

XSLT Developer's Guide


Introduction to XSLT

Within a few months of the introduction of XML came the introduction of the Extensible Stylesheet Language (XSL). This early XSL standard tried to incorporate the following two functionally different operations under a single process:

  • Styling—Controlling the manner in which the content appears. This operation covers visual display characteristics, such as font attributes, boxes, and so on, and also allows for non-visual presentations of content, particularly aural presentation.
  • Transforming—Parsing an input document into a source tree with a collection of distinct nodes, and then converting that tree into a separate, perhaps quite different, result tree.

Since that time, XSL has gone through several permutations, the most important of which was a split into XSL proper—specifications for how to display document content—and XSL Transformations (XSLT)—specifications on how to transform data from one document to another.

The future of XSL

XSL is now generally referred to as XSL Formatting Objects (XSL-FO) to distinguish it from XSLT. The extent to which it will be widely adopted is still uncertain, because much of its functionality overlaps with that already provided by CSS and indeed the HTML tag set. Also, there are currently no XSL-FO processing applications in common use. Thus, for now, XSL-FO standalone style sheets serve largely an academic function. Until the XSL-FO standard moves to full Worldwide Web Consortium (W3C) recommendation status, vendors are unlikely to invest resources in supporting it in more than limited experimental ways. So—again, for now—the XSL-FO portion of the original XSL Working Draft is in limbo.

The future of XSLT

XSLT, on the other hand, in its brief history has already become profoundly successful. Its purpose is to transform marked-up documents into something else. For instance, you can convert an XML document into HTML, or into a comma-separated-values (CSV) flat file, or into another XML vocabulary. Originally, XSLT used a pattern-matching syntax of its own. Later, with the availability of the XML Path Language (XPath) specification, XSLT adopted XPath as its pattern-matching tool.

See Also

Comparing XSLT to Cascading Style Sheets | Using XSLT with Cascading Style Sheets


Comparing XSLT to Cascading Style Sheets

While it is possible to style data by embedding formatting elements into Extensible Stylesheet Language Transformations (XSLT) files, the real purpose of XSLT is not to format data but to transform and manipulate data. The best way of formatting data (especially data in large, complex documents) for display in a browser is through cascading style sheets.

Provided that the structure of an XML document is virtually identical to the structure of how you want to display the content, then you could use a cascading style sheet directly with the XML data and not even use XSLT. However, if you want to change the order of, augment, or manipulate the elements in a document, then you need to incorporate XSLT into the process.

File Type Advantages Disadvantages
XSLT
  • Can reorder, add, or delete elements since XSLT is aware of the structure of the XML document
  • Can incorporate content from more than one document or split a single document into many
  • Able to access and manipulate the comments, processing instructions, and attribute values and names within an XML document
  • Written using XML so there is no third language to be learned
  • Offers simple programming-like logic which includes an almost infinite variety of conditional statements and the ability to perform operations such as addition and
  • Can include text and graphics
  • Generate a variety of output: static or dynamic HTML, XML, RTF, PDF, comma-separated-values (CSV) flat files, or a stream of XSL Formatting Objects (XSL-FO)
  • Is not a style language in itself so the application that handles the output from XSLT must be able to style it accordingly
  • Requires character escaping to output special markup characters such as "<" and "&".
  • Uses more memory and processor power since reordering, adding, deleting, and manipulating elements requires a tree representation of the document in memory
  • Is more difficult to learn to use
Cascading Style Sheet
  • Is simple to use
  • Is suitable for simple documents
  • Uses less memory since it cannot reorder a document and, thus, does not need to build a tree representation of the document
  • Starts displaying the document as soon as it begins processing the document
  • Has widespread support by the developer community
  • Cannot reorder, add, delete, or perform operations on elements
  • Offers no access to non-elements (attributes and their values, processing instructions, and so on)
  • Cannot style non-textual content (such as images) referred to in an XML document
  • Has limited support for version 2 in many applications
  • Uses a different syntax than XML, so requires completely separate parsers and APIs
  • Outputs only data suitable for viewing in a Web browser

Note For more information about cascading style sheets, see the Cascading Style Sheets at the World Wide Web Consortium (W3C) Web site.

See Also

Using XSLT with Cascading Style Sheets

Other Resources Other Resources

Cascading Style Sheets


Using XSLT with Cascading Style Sheets

When thinking about how to use Extensible Stylesheet Language Transformations (XSLT) and cascading style sheets, it is important to keep in mind exactly what the purpose of each of the technologies is and how the XML Path Language (XPath) fits in:

  • XPath is the method by which you select the exact data that you want to transform or use. It does this by providing you with a way to match patterns to specific data in the document.
  • XSLT is the method by which you manipulate, add, or delete the data that you select using XPath. You can use XSLT to transform data into a variety of output, not just XML or HTML.
  • Cascading style sheets are the method by which you format HTML content output by XSLT for display in a browser.

Keeping in mind how each of these technologies relates to the others, the following table outlines which technologies need to be used based upon the desired output.

Note In the following table, XPath has not been called out since the use of XPath is inherent with the use of XSLT. Thus, the term, "XSLT," implies the use of XPath as well.

Type of Output | Output to be | Requires
XML document, comma-separate-values (CSV) flat file, or other text-based file | Stored in a database or other location in memory??? | XSLT
Simple HTML document that matches the structure of the source document | Displayed in Microsoft® Internet Explorer 5.0 or later | XSLT —or— Cascading style sheet
 | Displayed in a browser other than Internet Explorer 5.0 or later | Cascading style sheet
Complex HTML document | Displayed in Microsoft® Internet Explorer 5.0 or later —and— All clients meet minimum memory and processing requirements | XSLT with embedded style tags
 | Displayed in Microsoft® Internet Explorer 5.0 or later —and— All clients do not meet minimum memory and processing requirements | XSLT (performed on the server) —and— Cascading style sheets (performed on the client)

See Also

Comparing XSLT to Cascading Style Sheets


Understanding the XSLT Process

This illustration shows the various input files and output destinations for an XSLT transformation. The input and output can be any text format. The most common transformation uses an XML file as input and an HTML document as output. Click on a colored area in this illustration to find out more about that component.


XSLT Document Map

The following XSLT document contains many of the features commonly found in XSLT files. Click on the colored text for more information about each common component of an XSLT file.

For more information about running this file along with its auxiliary files, see Sample Files for the XSLT Document Map.

See Also

Document Map (XML Developer's Guide)


Sample Files for the XSLT Document Map

This example includes the XSLT file used in the XSLT Document Map.

The example demonstrates using the key() function and <xsl:key> element to group data into categories.

The mode attribute is used to produce two different tables from the same XML data. For more information about modes, see xsl:apply-templates Element.

XML File (books.xml)

Use the Sample XML File (books.xml). Below the line <?xml version='1.0'?>, add the following line:

<?xml-stylesheet type="text/xsl" href="books.xsl"?>

Ancillary XML File (ancillary.xml)

The above XSLT file loads the following XML file to demonstrate the document() function:

<?xml version='1.0'?>
<document>
   <watermark>Scootney Publishing</watermark>
   <copyright>Copyright 2000, Scootney Publishing. All Rights Reserved.</copyright>
</document>

XSLT File (books.xsl)

This file is the same one as shown in the document map. It provides examples of common tagging within an XSLT file.

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:variable name="recentdate">2001-01-01</xsl:variable>
<xsl:variable name="ancillary" select="document('ancillary.xml')"/>
<xsl:key name="categ_key" match="book" use="genre"/>
<xsl:key name="author_key" match="book" use="author"/>

<xsl:template match="/">
   <html>
      <head>
         <title>Scootney Publishing: Special Exhibit</title>
         <style>
            h1 {font-family: Arial,Helvetica,Univers,sans-serif;
                font-size: 18pt; background-color: #00CCCC; width: 90%}
            h2 {font-family: Arial,Helvetica,Univers,sans-serif;
                font-size: 14pt; width: 90%}
            h3 {font-family: Arial,Helvetica,Univers,sans-serif;
                font-size: 12pt; background-color: gold;
                width: 90%; border-width: 1; border-style: solid}
            h4 {font-family: Arial,Helvetica,Univers,sans-serif;
                font-size: 11pt; background-color: gold;
                width: 33%; border-width: 1; border-style: solid}
         </style>
      </head>
      <body>
         <div style="position:absolute;font-size:96;
               font-family:Times New Roman;color:#F0F0F0;z-index:-1">
            <xsl:value-of select="$ancillary//watermark"/>
         </div>
         <h1>&#xA0;Scootney Publishing: Special Exhibit Catalog</h1>
         <!-- Group by catalog in first pass, then by author -->
         <xsl:apply-templates select="catalog" mode="grp_categ"/>
         <xsl:apply-templates select="catalog" mode="grp_author"/>
         <p/>
         <div style="font-size:9">
            <xsl:value-of select="$ancillary//copyright"/>
         </div>
      </body>
   </html>
</xsl:template>

<xsl:template match="catalog" mode="grp_categ">
    <h2>Titles Grouped by Genre</h2>
    <xsl:for-each select="book[count(. | key('categ_key', genre)[1])=1]">
        <h3>&#xA0;<xsl:value-of select="genre"/></h3>
        <xsl:for-each select="key('categ_key', genre)">
            <xsl:sort select="title"/>
            <table border="0" width="75%">
                <tr>
                    <th width="10%" align="right">Title</th>
                    <td width="90%" align="left"><xsl:value-of select="title"/></td>
                </tr>
                <tr>
                    <th width="10%" align="right">Author</th>
                    <td width="90%" align="left"><xsl:value-of select="author"/></td>
                </tr>
                <tr>
                   <th width="10%" align="right">Copyright</th>
                   <td width="90%" align="left">
                      <xsl:value-of select="publish_date"/>
                      <xsl:if test="substring(publish_date,1,4) &gt;= substring($recentdate,1,4)">
                         &#xA0;&#xA0;<b>new</b>
                      </xsl:if>
                   </td>
                </tr>
                <tr>
                    <th width="10%" align="right">Price</th>
                    <td width="90%" align="left"><xsl:value-of select="price"/></td>
                </tr>
                <tr>
                    <th width="10%" align="right" valign="top">Summary</th>
                    <td width="90%" align="left"><xsl:value-of select="description"/></td>
                </tr>
            </table>
            <hr width="75%" align="left"/>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

<xsl:template match="catalog" mode="grp_author">
    <h2>Titles Grouped by Author</h2>
    <xsl:for-each select="book[generate-id() = generate-id(key('author_key', author)[1])]">
        <xsl:sort select="author"/>
        <h4>&#xA0;<xsl:value-of select="author"/></h4>
        <xsl:for-each select="key('author_key', author)">
            <xsl:sort select="title"/>
            &#xA0;<xsl:value-of select="title"/><br/>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Formatted Output

You can view the output in Microsoft® Internet Explorer.

See Also

Document Map (XML Developer's Guide) | Grouping Data by Examining the Keyed Node-set


XML Declaration in an XSLT File

An XSLT file is an XML file. It is recommended that an XSLT file start with an XML declaration, such as <?xml version="1.0" encoding="UTF-8"?> so various applications can recognize what type of data the file contains.

See Also

XML Declaration (XML Developer's Guide)


XSLT Stylesheet Declaration

The following is a typical XSLT stylesheet declaration.

<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

The stylesheet declaration usually declares the version of XSLT and typically declares between one and three namespace declarations.

See Also

xsl:stylesheet Element


Namespace Prefix Declarations

There is always at least one namespace declaration as an attribute in the <xsl:stylesheet> element, usually xmlns:xsl="http://www.w3.org/1999/XSL/Transform". This particular namespace declaration is required for the <xsl:stylesheet> element itself, which uses the xsl prefix. Elements and other parts of an XSLT file use a namespace prefix, such as "xsl" in <xsl:if>.

If there is no prefix, the default namespace is assumed. The default namespace is usually used for literal result elements.

See Also

Using Namespaces in Documents (XML Developer's Guide) | Declaring Namespaces for XSLT | Working with Namespaces and Prefix Aliases | Declaring the msxsl: Namespace Prefix


Namespace Prefixes in XSLT

A namespace prefix acts as an alias for a fully expanded namespace string. The namespace string does not point to anything, unless it starts with ___. xmlns="urn:schemas-mycompany-com:xslt".

Common Namespace Declarations

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns="urn:schemas-mycompany-com:xslt"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
      xmlns:fo="http://www.w3.org/1999/XSL/Format">

The following is a deprecated namespace declaration for an early dialect of Microsoft XSL such as shipped with Internet Explorer 5.0:

xmlns:xsl="http://www.w3.org/TR/WD-xsl"

It is recommended that you use the default namespace for literal result elements, such as <html> and <h2>.

See Also

Working with Namespaces and Prefix Aliases | Declaring the msxsl: Namespace Prefix


Output Method Declarations

After an XSLT transformation produces a result tree, the <xsl:output> element is used by the processor to determine how to serialize the result tree. The output method attribute can be xml, html, or text. This element is usually placed after the <xsl:stylesheet> element. If the output is not serialized, but is instead made available as a tree, such as in the DOM API, this element is ignored. This element must be a child of the <xsl:stylesheet> element.

<xsl:output method="xml"/>
<xsl:output method="html"/>
<xsl:output method="text"/>

See Also

Controlling Output Format with the media-type Attribute | xsl:output Element


XSLT Variables and Parameters

In XSLT, variables serve the same purpose as constants in programming and scripting languages. They identify generically named objects, from each of which a value can be retrieved as needed. An XSLT variable cannot be updated during runtime.

The variable's value is set by some condition in the XML source document or in the style sheet. These conditions can change from one transformation to the next, therefore these objects are known as variables rather than constants.

The <xsl:variable> element declares a variable and defines its value. You can use either syntax:

<xsl:variable name="bookCount">3</xsl:variable>
<xsl:variable name="bookCount" select="3"/>

The syntax that has the select attribute enables more complex expressions.

A variable can be used to avoid repeating a calculation, to provide a central place for setting a value, or for referring to a particular result tree fragment. If the variable is declared immediately within the <xsl:stylesheet> element, it is a global variable. If it is declared within the body of a template rule, it is a local variable and only can be referenced within the scope of that block.

The XSLT document map provides an example of defining and referencing a variable.

XSLT Parameters

A parameter has a value. A reference to a parameter is a dollar sign ($) followed by the name of the parameter.

The value of a parameter can change during a given run of a given style sheet, and can be passed in from the outside environment.

Local parameters are used to pass data from one template rule to another. For example, you can pass a parameter to a named template, based on some condition in a given template rule. You can thereby control the way the named template behaves. This is similar passing an argument to an XPath or XSLT function.

Global parameters are use to pass a value from outside the style sheet to the style sheet. This enables the style sheet to perform particular steps depending on a supplied value such as a value supplied by the user. In Microsoft Internet Explorer, parameters are passed to a style sheet using scripting.

See Also

Using XSLT Variables and Parameters | Design Patterns for Using Variables and Parameters | Passing Parameters Using Named Templates | xsl:variable Element | xsl:param Element


Template Rules

Each <xsl:template> element or template rule consists of two components: a match pattern and the template itself.

<xsl:template match="region">
[template]
</xsl:template>

Match Patterns

The match pattern consists of a match attribute and an XML Path Language (XPath) expression, specifying which portions of the source tree to select for processing by the template rule. For example,

<xsl:template match="region">

processes all <region> elements in the source tree.

Similarly,

<xsl:template match="@books_sold">

selects all the books_sold attributes for processing.

Since match patterns are XPath-based, they need not select just an element from the source tree, but can select text, processing instructions, comments, CDATA declarations, and so on. For more information, see Using XPath Expressions to Select Nodes.

Template

The template places content in the result tree each time that the template locates something in the source tree that matches the match pattern. That is, the template rule instantiates the template for each such match.

Exactly what goes into a given template depends on how the template is to transform the source document. If transforming to HTML, for instance, the template may consist of HTML markup, plain text content, comments, scripts, and so on.

See Also

How XSLT Template Rules Depend on Context | Using Named Template Rules in XSLT | xsl:template Element | xsl:apply-templates Element | xsl:call-template Element


Literal Result Elements in XSLT Files

An XSLT file can contain elements that are in the XSLT namespace, such as <xsl:if>, and these elements are interpreted as XSLT code to be processed. Elements in the XSLT file that are not in the XSLT namespace, such as <html>, <body>, <p>, and <h2>, are treated as literal result elements and are copied to the output with minimal processing. HTML elements in the XSLT file need be closed; be sure there is a closing slash, such as <br/> or </p>.

See Also

Replacing Elements Using a String Literal instead of <xsl:value-of>


XPath Expressions

An XPath expression selects a node or nodes that match the specified pattern and criteria. The expression is run against a node tree representation of an XML document.

See Also

Lesson 2: Using XPath Pattern Matching to Transform Elements | Using XPath Expressions to Select Nodes | XPath Syntax | XPath Examples | Location Path Examples


Comments in XSLT

Comments in XSLT work the same as comments in XML. You can comment out a block of XSLT elements. You cannot comment out text inside a start-tag, such as <xsl:value-of <!-- mycomment--> select="book">.

See Also

Generating Comments, Processing Instructions, and Elements | xsl:comment Element | Comments (XML Developer's Guide)


<xsl:for-each> Loops

The <xsl:for-each> element establishes the context for iteration; the XSLT transformation instructions within the for-each loop are applied to each of the nodes selected by the select attribute of the <xsl:for-each> element. Each source element selected by <xsl:for-each> becomes a new context against which any pattern matching within the <xsl:for-each> occurs.

Example

<xsl:for-each select="//book">
   <tr>
      <td>
         <xsl:value-of select="author"/>
      </td>
      <td>
         <xsl:value-of select="title"/>
      </td>
   </tr>
</xsl:for-each>

See Also

Lesson 3: Looping Using <xsl:for-each> | xsl:for-each Element


XPath Functions and XSLT Functions

An expression in XSLT can include a function call.

A function returns a value.

XSLT has a variety of predefined functions.

See Also

Using Functions in XPath Expressions | Using the key() Function | Design Patterns for Scripting and Extension Functions | XSLT Functions | XPath Functions


Conditional Statements

If the expression in an <xsl:if>, <xsl:when>, or <xsl:otherwise> element evaluates to true, the template body inside that conditional element is instantiated.

There are two kinds of conditional constructions: if, and choose/when/otherwise. For a simple statement that either does or does not performs an action, use if. To perform one action for one condition but a different action for a different condition, use choose/when/otherwise.

The test attribute contains the expression to evaluate, and can be a comparison or an XPath expression. The expression evaluates to true if the expression returns any of the following:

  • A non-empty node-set
  • A non-zero number
  • A non-empty result tree fragment
  • A non-empty string

Example of <xsl:if>

<xsl:for-each select="//book">
   <tr>
      <td>
         <xsl:value-of select="title"/>
      </td>
      <td>
         <xsl:attribute name="bgcolor">lightyellow</xsl:attribute>
         <xsl:if test="price &gt; 10">
            <xsl:attribute name="bgcolor">lightgreen</xsl:attribute>
         </xsl:if>
         <xsl:value-of select="price"/>
      </td>
   </tr>
</xsl:for-each>

Example of <xsl:choose>

<xsl:for-each select="//book">
   <div>
      <xsl:choose>
         <xsl:when test="self::*[genre = 'Romance']">
            <xsl:attribute name="style">background-color: pink</xsl:attribute>
         </xsl:when>
         <xsl:when test="self::*[genre = 'Fantasy']">
            <xsl:attribute name="style">background-color: lightblue</xsl:attribute>
         </xsl:when>
         <xsl:otherwise>
            <xsl:attribute name="style">background-color: lightgreen</xsl:attribute>
         </xsl:otherwise>
      </xsl:choose>
      <xsl:value-of select="title"/>
   </div>
</xsl:for-each>

See Also

Lesson 5: Adding a Conditional Statement | Defining Conditional Templates Using <xsl:if> and <xsl:choose> | xsl:choose Element | xsl:if Element


External Document References

The XSLT document() function refers to an XML file or an XML document and enables you to select and extract data from the XML file.

In the context of XSLT, the words "import" and "include" usually concern other XSLT files, rather than XML files.

  • <xsl:import> includes another style sheet into the current style sheet. The imported definitions and template rules have lower priority.
  • <xsl:include> includes another style sheet into the current style sheet. The imported definitions and template rules have the same priority as the importing style sheet. The <xsl:include> element is only allowed as the child of the <xsl:stylesheet> element.

See Also

Lesson 6: Extracting Data from Other Documents | Processing an External Document Using document() | document Function | Importing and Including Style Sheets


The XSLT Processor

The process involved in transforming a source document into a results document begins with the Microsoft XML Parser (MSXML) parsing the source document and the Extensible Stylesheet Language Transformations (XSLT) file into the DOM. From there, the XSLT processor portion of MSXML starts applying the transformation information contained in the XSLT file to the source document.

The following illustration shows the processing relationship among the XSLT processor, XSLT tree, source tree, and result tree. Click on a colored area in the illustration to find out about that particular part of this relationship.

Parsing the Documents into Trees in the DOM

MSXML parses both the source file and XSLT file into a source tree and XSLT tree, respectively. Parsing the source file into a tree is critical since the XML Path Language (XPath) is not able to navigate a source document directly. XPath treats XML documents as trees with interrelated nodes. So, by parsing a source document into a tree, XSLT is able to to use XPath to navigate that tree.

Part of the parsing process is to check the documents to make sure they have well-formed XML. Processing halts with an error message if the document isn't well-formed.

Transforming and Outputting Data

The XSLT processor begins the transformation process by first looking at the transformation information stored in the XSLT tree. This transformation information is in the form of template rules.

As the XSLT processor processes the template rules, the processor outputs the transformed data into a result tree. This result tree can be either XML or any other structured text content, such as HTML, comma-separated-values (CSV) flat files, or RTF documents.

See Also

Working with a Source Tree | Processing Template Rules | Linking to an XSLT File


Working with a Source Tree

To locate the data to be transformed, the Extensible Stylesheet Language Transformations (XSLT) processor needs to navigate the document's source tree. The XSLT processor is able to do this since XSLT uses the XML Path Language (XPath) to locate and select data.

XPath treats an XML document as a tree. Each separate location on this tree is a node, and a collection of nodes is a node-set.

In XPath, a node can be one of seven different types, as shown in the following table. However, not all documents contain all seven nodes and not all seven nodes actually have an element representing them. For instance, while there is a root node, there is no actual element representing that node. Likewise, while XPath treats namespaces as node, there is no representation of these nodes in the source tree found in the DOM.

Node Type | Description
Root | Corresponds to a context to the source document itself
Element | Corresponds to every element in a source document
Attribute | Corresponds to the attributes specified for an element.
Text | Corresponds to actual character data within the source document.
Namespace | Corresponds to each distinct namespace prefix that is in scope for the element (including the xml prefix, which is implicitly declared) and to the default namespace if one is in scope for the element. Namespace nodes may or may not be present in a document.
Processing-instruction | Corresponds to every processing instruction contained in the source document, except for those processing instructions found within the document type declaration.
Comment | Corresponds to every comment contained in the source document, except for those comments found within the document type declaration.

See Also

XPath Nodes Example | The XSLT Processor


XPath Nodes Example

To help illustrate the nodes used by the XML Path Language (XPath), the following graphic represents the source tree for the first book element in the Sample XML File (books.xml). This source tree represents the nodes that are accessible using XSLT. If you compare the source file to the source tree represented here, it becomes obvious that not all the objects within the document appear in this source tree. For instance, the source tree does not have nodes for the <?xml-stylsheet> and DOCTYPE elements that appear in the document prolog. This missing objects still exist in the DOM and, while you cannot access them directly using XPath and, by extension the Extensible Stylesheet Language Transformations (XSLT), you can access them programmatically instead.

Note While information in a document's prolog is not typically accessible, XPath and XSLT are able to access it because the document has been fully parsed by the time the XSLT processor accesses the document tree.

See Also

Working with a Source Tree | Using XPath to Select Nodes | The XSLT Processor


Processing Template Rules

When the Extensible Stylesheet Language Transformations (XSLT) processor starts processing the XSTL tree, the processor initially looks for the template rule that points to the document root element in the source tree.

At its simplest, the template rule that points to this root element is as follows:

<xsl:template match="/firstelement">

Here the value of the match pattern indicates this rule applies to the first element (symbolized by firstelement) of the root node (symbolized by the slash, /). In the Sample XML File (books.xml), the simplest template rule that points to the document root element is <xsl:template match="/catalog">.

Once the XSLT processor locates this initial template rule, the processor evaluates the rule and proceeds based upon that evaluation:

  • If this rule has no conditional statements, it most likely directs the processor to simply transform this document root element. In this case, the processor transforms the root element and then looks for a template rule that matches the next highest element in the source tree, transforms that element, and then looks for the next highest element. This process continues for all the elements in the source tree.
  • If this rule contains conditional statements, the processor evaluates each statement and executes the appropriate conditional statement. Often, each of these conditional statements direct the XSLT processor through a series of template rules that are specific to the conditional statement. Essentially, this means that the XSLT processor ignores all template rules associated with other conditional statements.

Controlling Processing

As you might have noticed, the processing of an XSLT file is not procedural like in most programming languages. That is, the XSLT processor does not sequentially process each template rule as it appears in the XSLT tree.

Under certain circumstances, however, the sequence in which the style sheet is processed may be determined and to a limited extent controlled:

  • Using Conditional Processing—XSLT provides the <xsl:if> and <xsl:choose> elements for testing conditions. By using these elements, an XSLT file can direct the processor through a specific series of templates.
  • Importing Other Style Sheets—An XSLT file may import other XSLT files, and the order in which the corresponding <xsl:import> elements' appear in the original file determines an import precedence that determine the order in which the processor applies the other XSLT files.

Handling Template Rule Conflicts

While processing an XSLT tree, the XSLT processor may encounter a few conflicts that need to be resolved:

  • If the processor finds multiple template rules that match a given node, the processor needs to decide which of these template rules to use. For more information about how the processor makes this decision, see Processing Multiple Matching Templates Rules.
  • If there are no matches, the processor falls back on one of the built-in template rules to decide how to handle the node. For more information about these built-in template rules, see Understanding the Built-in Template Rules.

See Also

The XSLT Processor


Processing Multiple Matching Template Rules

If more than one template rule matches a given node in the source tree, the Extensible Stylesheet Language Transformations (XSLT) specification provides a set of rules by which to resolve such conflicts.

In general, these rules say to apply the match pattern which most closely corresponds to the node in question. Specifically, these rules are:

  1. Select the pattern with the highest import precedence. (An XSLT file may import other XSLT files, and the order in which the corresponding <xsl:import> elements' appear in the original file determines an import precedence.) If there is still more than one match after this step, proceed to the next step.
  2. Assign a numeric priority to each conflicting pattern (as shown in the following table) and select the pattern with the highest priority. If there is still more than one match after this step, proceed to the next step.

    Assign a priority of | If the match pattern
    0 (zero) Is an element or attribute name

    —Or—

    Is a processing instruction with a specific target
    -0.25 | Includes the wildcard character (*)
    -0.5 | Consists of just a node test, such as text() for selecting nodes
    0.5 | Does not match any of the other criteria

    Note If the pattern contains a pipe symbol (|) that specifies alternate XML Path Language (XPath) expressions, treat each expresssion as if it were a separate match pattern.
  3. The XSLT processor is free either to treat the multiple matches as an error condition or to accept, by default, the last matching pattern. Most XSLT processors, including the Microsoft XML Parser (MSXML), accept this default.

See Also

Processing Template Rules | Understanding the Built-in Template Rules


Understanding the Built-in Template Rules

The Extensible Stylesheet Language Transformations (XSLT) specification requires XSLT processors to support a number of built-in template rules. If there is no explicit template rule which applies to a given node in the source tree, the processor falls back on one of these built-in rules.

Rules for Root and Element Nodes

If explicitly declared in a style sheet, the built-in template rule for the root and element nodes looks like:

<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>

This rule instructs the processor to recursively process all children of the root and all element nodes, according to the template rules explicitly included in the style sheet. If for some reason you want the processor to ignore all nodes in the source tree unless it finds a match for an explicit template rule, you can override this built-in rule by making the <xsl:template> element empty:

<xsl:template match="*|/" />

Rules for Text and Attribute Nodes

The following built-in template rule handles all text content bound to element nodes:

<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>

For every text or attribute node which, this template specifies that the text content of each matched node is to be output straight to the result tree.

Note Since XSLT treats newline characters, along with other white space characters, as text nodes, this built-in rule applies to white space characters as well. For more information about XSLT and white space, see Overriding <xsl:preserve-space> and <xsl:strip-space>.

Rules for Comment and Processing Instruction Nodes

For most applications, XSLT considers comments and processing instructions extraneous to the result. Consequently, the built-in rule for handling them suppresses their output in the result tree, using an empty <xsl:template> element:

<xsl:template match="processing-instruction()|comment()" />

For a given application, it may be important for the processor to copy comments to the result tree, as in the case where an XHTML source tree includes <script> elements with the actual script's source code hidden from older browsers by being embedded in comments. In such a case, the following explicit template rules override the built-in rule:

<xsl:template match="processing-instruction()" />

<xsl:template match="comment()">
    <xsl:value-of select="." />
</xsl:template>

See Also

Processing Template Rules | Processing Multiple Matching Templates Rules


Linking to an XSLT File

The Extensible Stylesheet Language Transformations (XSLT) processor knows to apply a specific XSLT file to a specific source document because the source document somehow links to the XSLT file. To establish this link, you either insert a style sheet processing instruction into the source document itself or set up this link programmatically using the DOM.

From a performance standpoint, it does not matter whether you link using a stylesheet processing instruction or through the DOM. The difference between these two methods really focuses on the underlying data, as outlined in the following table.

Link Using If
A Style Sheet Processing Instruction
  • The data is fairly static (changes little, if at all).
  • There is no need for dynamic transformations which include the passing of parameters.
The DOM
  • The data is dynamic.
  • You want to dynamically evaluate the data by passing parameters or performing dynamic transformations.
  • You want a more modularize approach that is easier to maintain.

Note For ease in learning XSLT, many of the samples in this section use a style sheet processing instruction to link to the XSLT file. These samples would work just as well if you link them using the DOM instead.

See Also

Linking Using a Processing Instruction | Linking Using the DOM | Displaying Transformation Results | The XSLT Processor


Linking Using a Processing Instruction

If you link to an Extensible Stylesheet Language Transformations (XSLT) file using a style sheet processing instruction, that instruction needs to be at the beginning of an XML document, following the XML declaration (if there is one) and the document-type declaration (if there is one). For instance, the style sheet processing instruction needs to appear just after <?xml version ="1.0"?> in the Sample XML File (books.xml), as shown in bold in the following document fragment:

""""""""""""""<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="books.xsl" ?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
...

See Also

Processing Instructions | Linking to an XSLT File | Linking Using the DOM

Other Resources Other Resources

Associating Style Sheets with XML Documents, Version 1.0


Linking Using the DOM

Even if a source document does not include a style sheet processing instruction, you can use the DOM's transformNode or transformNodeToObject methods to transform the contents (in whole or in part) of the source document'.

To use either of these two methods, you first must load the source document into one instance of the Document object and the Extensible Stylesheet Language Transformations (XSLT) file into another object. Then, you apply one of the desired transformation method to the source object. Which method you apply depends upon the desired result:

transformNode
This method returns a string whose value is the result of applying the XSLT object to the source object. Typically, this value is HTML code for display in a Web page.
transformNodeToObject
This method places the result of the transformation into another object, which can then be manipulated further (as with a second transformation).

When using either method, the source object need not be a complete Document object; it may be simply a node of such an object. If it is just a node, the XSLT processor treats that node, and all of its descendants, as if they were a complete document. Likewise, the XSLT object may be a complete, standalone XSLT file or a node representing an embedded style sheet within an XSLT file.

See Also

transformNode Method | transformNodeToObject Method | Using XSLT from the DOM | Linking to an XSLT File | Linking Using a Processing Instruction


XSLT Output

Just as cascading style sheets brought new richness and interactivity to static HTML pages, Extensible Stylesheet Language Transformations (XSLT) extends the value of XML data. XSLT allows you to not only present XML data, but also to transform it into completely new data tailored specifically to a particular user, media, or client.

With XSLT, you can do the following.

  • Transform data so it can be exchanged between disparate business systems.

    XSLT excels at mapping one XML-based representation into another. For example, a book retailer may represent a customer order based on one schema while a book supplier may represent it with another schema. With XSLT, a customer order taken by the book retailer can be transformed into an XML-based representation that matches the book supplier's schema. Once transformed, the book retailer can send the order to the book supplier in an XML format that the book supplier understands.

  • Transform XML documents into HTML documents for a variety of browsers.

    XSLT transformations are useful not only for backward compatibility for older browsers, but are indispensable for transforming data so it can be rendered on the new Internet devices on the market, including Internet-enabled handheld PCs, mobile phones, and TV set-top boxes.

  • Transform XML data into a variety of media, including HTML documents for the Web and .PDF format for print.

    With XSLT, you can output XML to a variety of media, including HTML for the Web and Package Definition Format (PDF) for print.

  • Dynamically filter information to present information targeted to a specific user or user group.

    For example, for an XML-based catalog, you can use one style sheet to present one set of information to retail customers, while using another style sheet to present information to wholesale customers.


Setting Up XSLT

The Extensible Stylesheet Language Transformations (XSLT) processor is built into the Microsoft® XML Parser (MSXML) 4.0. This processor achieved full XSLT support with the release of MSXML 3.0. However, Microsoft products ship with different versions of MSXML. Therefore, you need to ensure that the computer on which you want to run XSLT solutions has a version of MSXML that fully supports XSLT.

For full XSLT support and access to all the latest MSXML features, you must install MSXML 4.0 on the computer on which you want to run XSLT solutions. Installation of MSXML 4.0 is necessary regardless of whether the computer running XSLT is the client or the server.

System Requirements for XSLT

The following are the system requirements for running MSXML 4.0:

  • Windows-compatible computer.
  • Microsoft Windows® 2000, Microsoft Windows NT® 4.0, Microsoft Windows 98, or Microsoft Windows 95.
  • Microsoft Internet Explorer 5.0 or later. (This is optional because you can create XSLT transformations using Microsoft Visual Basic® or C++ that produce output not intended for display on Internet Explorer.)

Installation

MSXML 4.0 installs in side-by-side mode. In this mode, MSXML 4.0 does not replace any existing versions of MSXML installed on the computer. Instead, the installation process simply downloads three files (msxml4.dll, msxml4a.dll, and msxml4r.dll) onto your computer and registers the msxml4.dll file in the computer's registry.

For more information, see Installing MSXML 4.0 for XSLT Support.

See Also

Setting Up an XSLT Development Environment | XSLT Utilities and Samples You Can Download


Setting Up an XSLT Development Environment

Creating XSLT solutions requires not only the system requirements described in Setting Up XSLT, but at least a text editor, such as Notepad.

However, to truly use XSLT, you should consider expanding upon these basic requirements with the additional system components outlined in the following table. This table describes two different XSLT development setups:

  • The minimum XSLT setup is for those developers who want to use XSLT with a minimum of overhead.
  • The recommended XSLT setup is for programmers who want a robust development environment for creating multitier applications that employ XSLT technology.

To | System Component | Minimum Setup | Recommended Setup
Develop XSLT files | Web development tools such as Microsoft FrontPage®, Microsoft Visual InterDev®, or a third-party HTML editor. —Or— A third party XML editor, such as XMetal 2.0 from SoftQuad or XML Spy 3.0 from XML Spy. | Yes | Yes
Display XSLT applications in a Web browser | Client computer with Internet Explorer 5.0 or later installed | Yes | Yes
Use Active Server Pages (ASP) on a server to run XSLT transformations | Server computer with either Microsoft Internet Information Services (IIS) or Microsoft Personal Web Server (PWS). (Optional) A database, such as Microsoft SQL Server™ 2000. |  | Yes
Develop stand-alone XSLT applications | Programming tools that support COM, such as Microsoft Visual Basic® Scripting Edition (VBScript), Microsoft JScript®, Microsoft Visual Basic, Visual Basic for Applications, or C++. (Optional) XSLT Utilities and Samples You Can Download |  | Yes

See Also

Installing MSXML 4.0 for XSLT Support


Installing MSXML 4.0 for XSLT Support

To set up your development environment to create Extensible Stylesheet Language Transformations (XSLT) solutions, you must install the Microsoft® XML Parser (MSXML) 4.0.

The installation process puts MSXML 4.0 in side-by-side mode on your computer. This means that MSXML 4.0 does not replace any existing versions of MSXML installed on the computer. The advantage of this installation option is that it does not alter the behavior of XML code written for earlier versions of MSXML. For example, different versions of the Microsoft Windows® operating system and Microsoft Internet Explorer are released with different versions of MSXML. Because MSXML 4.0 installs in side-by-side mode, developers who have created solutions based on earlier versions of MSXML can download MSXML 4.0 without destabilizing their existing XML code.

In side-by-side mode, calling applications using version-independent CLSIDs and ProgIDs will reference MSXML 4.0. To ensure the stability of your applications, however, it is recommended that you use version-dependent ProgIDs.

Coding to Version-Dependent ProgIDs

To create XSLT solutions that take advantage of MSXML 4.0 functionality, you create instances of objects using version-dependent ProgIDs.

The following Microsoft JScript® code shows how to create an instance of the DOMDocument object using the version-dependent ProgID, Msxml2.DOMDocument.4.0. This ProgID is for MSXML 4.0.

var xml = new ActiveXObject("Msxml2.DOMDocument.4.0");
var xsl = new ActiveXObject("Msxml2.DOMDocument.4.0");

In a similar way, to code to MSXML 2.6, use the following JScript syntax:

var xml = new ActiveXObject("Msxml2.DOMDocument.2.6");
var xsl = new ActiveXObject("Msxml2.DOMDocument.2.6");

For a list of version-dependent and version-independent ProgIDs, see GUID and ProgID Information. For more information about creating the DOMDocument object, see Using DOMDocument.

Limitation of Side-by-Side Mode

Even after installing MSXML 4.0 in side-by-side mode, data islands in Microsoft® Internet Explorer do not provide full MSXML 4.0 support. When you create a data island on a Web page and reference it as an object, the browser creates that object based on the version of MSXML used by the browser. For Internet Explorer 5.0 or later, this can be MSXML 2.0 or MSXML 2.5, both of which support Extensible Stylesheet Language (XSL), but not XSLT.

See Also

Setting Up an XSLT Development Environment | XSLT Utilities and Samples You Can Download


Deploying XSLT Solutions

You can run Extensible Stylesheet Language Transformations (XSLT) on a client or server. In the same way, you can use XSLT in company-wide intranet or worldwide Internet solutions. This section describes the issues involved in creating XSLT solutions on the client and server, and for creating XSLT solutions for the Internet.

Keep in mind that you can invoke XSLT programmatically using any programming language that supports COM, including Microsoft® JScript®, Microsoft Visual Basic® Scripting Edition (VBScript), Microsoft Visual Basic, or C++. XSLT is not limited to Web solutions. It also provides an alternative way to dynamically convert XML documents for Visual Basic and C++ applications and business objects.

The following topics discuss XSLT deployment issues.

  • Deploying XSLT in Internet Explorer
  • Deploying XSLT on the Client
  • Deploying XSLT on the Server


Deploying XSLT in Internet Explorer

There are several considerations when deploying Extensible Stylesheet Language Transformations (XSLT) with Microsoft® Internet Explorer. Because Internet Explorer 5.0 was released with earlier versions of the Microsoft XML Parser (MSXML) that do not support XSLT, you have the following options:

  • Code to the version dependent ProgIDs for MSXML 4.0. For information about installing MSXML 4.0 for XSLT support, see Installing MSXML 4.0 for XSLT Support and GUID and ProgID Information.
  • Use Extensible Stylesheet Language (XSL), the language that preceded XSLT. For more information about XSL, see the XSL documentation included with the MSXML 2.5 SDK, available from MSDN®.
  • Use XSLT on the server with Active Server Pages (ASP) to transform XML documents and send HTML output to the client. With this option, you do not need to be concerned about the version of MSXML running on the client.

See Also

Deploying XSLT on the Client | Deploying XSLT on the Server


Deploying XSLT on the Client

Although Extensible Stylesheet Language Transformations (XSLT) solutions can be created for browsers on the intranet, XSLT style sheets can also be used in C++ and Microsoft® Visual Basic® applications (for example, a parts inventory or a Human Resources application) running on the user's desktop.

Client Setup

Because different versions of the Microsoft Windows® operating system are released with different versions of the Microsoft XML Parser (MSXML), it may be necessary to code to version-dependent ProgIDs (see Installing MSXML 4.0 for XSLT Support and GUID and ProgID Information) in MSXML to ensure that the client is capable of running XSLT.

Advantages of Transforming on the Client

Since the Microsoft XML Parser (MSXML 3.0) parser is not widely available in Microsoft Internet Explorer 5.5 (and XML in general is not widely deployed on any browsers besides Internet Explorer, though that is changing), any client side solution is currently within the realm of an intranet, rather than the Internet.

Given this, there are several reasons to deploy XSLT on the client, especially if you can control the browser version. You can explicitly associate several XML documents with a single XSLT file and then send both documents and the XSLT file to the browser. Once you load an XSLT document into memory, that document is cached and the next document to reference that style sheet automatically uses the cached version, reducing download time.

While server-dominated systems have limited ability to save state, you can maintain state sessions on the client by using Microsoft JScript or Microsoft Visual Basic Scripting Edition (VBScript) code on the client. This enables you to create applications that are more similar to a traditional Windows application than to Web interfaces. Moreover, you can take advantage of capabilities that more sophisticated browsers such as Internet Explorer 5.5 have: behaviors, drag and drop interactions, DHTML, the ability to work with ActiveX controls, and more.

Lastly, client-side scripting enables using the ServerXMLHTTP component to send XML information directly back to the client without forcing a page update. The combination of the XMLHTTP component and XSLT is a powerful combination, because you can pull in just the information that you need from the server, transform it into a suitable form of output, and both reduce the bandwidth of information being transmitted and the loss of context that converting XML into HTML entails.

See Also

Deploying XSLT in Internet Explorer | Deploying XSLT on the Server


Deploying XSLT on the Server

Server-side transformation of XML using Active Server Pages (ASP) is a viable solution for sending HTML to downstream browsers.

Server Setup

Because different versions of the Microsoft Windows® operating system are released with different versions of the Microsoft XML Parser (MSXML), it may be necessary to code to version-dependent ProgIDs (see Installing MSXML 4.0 for XSLT Support and GUID and ProgID Information) in MSXML to ensure that the server is capable of running XSLT.

Advantages of Transforming on the Server

Transforming the content on the server has the following advantages:

  • Single Point of Entry. Because the server can determine the client capabilities, the same page can service any kind of device, and can also consolidate a number of your sites sections into a single manageable interface.
  • Smaller Downloads. You send to the server only the absolute minimal amount of code necessary to display the page. Script in particular can be significantly reduced.
  • Error Control. You can better handle errors on the server in a transparent fashion than you can on the client.
  • Data Access and Security. Data access on the client is an expensive operation, as it involves not just moving information but also controlling access. By moving much of this to the server, you can effectively limit the amount and type of information that needs to be sent.
  • Reduced Coding. You can leverage existing blocks of both scripting and markup code, making it possible to create just-in-time web pages.
  • Better Content Management. By keeping your transformations on the client you can more effectively integrate documents in a transparent manner -- the users see only a complete document, not the various sub-documents that generate the document. This also makes it easier to make major changes to pages without disrupting the underlying content.
  • Stability of Platform. With server-side content generation you have complete control over the platform used to create the output, so you don't have to worry as much about versioning issues, problematic memory situations and instability of the client. Moreover, you can more intelligently plan your code resources and use features like Microsoft Transaction Server (MTS) to better distribute your internal resources.
  • Business Logic. If most of your data is XML based, then XSLT makes a very effective tool for writing business logic to both validate and manipulate the XML. Because business logic typically involves proprietary (and potentially insecure information) performing these transformations on the server can give you both improved performance and security than dealing with client side code.

Disadvantages of Transforming on the Server

The major disadvantage to using XSLT on the server is that state management becomes more problematic. Since you can save XML code in server side session variables, this can have an adverse impact on performance (especially when dealing with Web farms). Thus, you need to start thinking of solutions that are largely stateless, except perhaps for cookies, query and form string parameters, and similar light weight state tokens.

Another solution for handling state is to look at such solutions as the Simple Object Access Protocol (SOAP). SOAP has rapidly become the protocol of choice for exchanging messages between components outside of Windows proper, and can also be used internally through such services as Microsoft C# and Visual Studio 7. Because SOAP is an XML protocol, it can also be manipulated via XSLT, making XSLT oriented messaging systems feasible. For more information about SOAP, see the MSDN XML Developer Center.

See Also

Deploying XSLT in Internet Explorer | Deploying XSLT on the Client


Learning XSLT (A Tutorial)

The goal of this tutorial is to quickly familiarize you with transforming XML data using the Extensible Stylesheet Language (XSL) and XSL Transformations (XSLT).

In this tutorial, you first create an XML document that stores the regional sales data for Scootney Publishing. You then create an XSLT file that displays the regional sales data in the form of a sales report. You do all this in a series of six steps:

  • Lesson 1: Creating the XML Data File
  • Lesson 2: Using XPath Pattern Matching to Transform Elements
  • Lesson 3: Looping Using <xsl:for-each>
  • Lesson 4: Summing Data
  • Lesson 5: Adding a Conditional Statement
  • Lesson 6: Extracting Data from Other Documents

For reference, the following is also provided:

  • Final Files Produced in the XSLT Tutorial
Note Bold text is used in some of the code listings so you can immediately see the most important parts of the tagging for the current step.

For this tutorial, you will create the following files:

File name | Description
Sales.xml | An XML file containing the input data.
Transform.xsl | An XSLT file used to transform the input data.
Ancillary.xml | An XML file from which the XSLT file extracts additional data.

Requirements for the Tutorial

To run this tutorial, you need:

  • The current version of Microsoft® XML Parser (MSXML 4.0), available from the MSDN® Online Downloads.
  • Microsoft Internet Explorer 5.0 or later.
  • An HTML editor, such as Notepad.
  • (optional) Internet Explorer Tools for Validating XML and Viewing XSLT Output. This optional utility adds the View XSL Output and Validate XML commands to the right-click menu of Internet Explorer.

Other Resources Other Resources

Internet Explorer Tools for Validating XML and Viewing XSLT Output


Lesson 1: Creating the XML Data File

In Lesson 1, you create the Sales.xml data file which describes the number of books sold per quarter in several sales regions. This XML file is the input file, which will be transformed by the XSLT file.

Note The Sales.xml file created in this lesson is a preliminary version of the final Sales.xml file as it does not yet specify an Extensible Stylesheet Language Tranformations (XSLT) file to use.

To create the Sales.xml file

  1. Create a folder on your computer, such as C:\Documents and Settings\jsmith\My Documents\xsltTut.
  2. Using your HTML or text editor, create a new file and copy the following code into that file.
    <?xml version="1.0"?>
<sales>
   <summary>
      <heading>Scootney Publishing</heading>
      <subhead>Regional Sales Report</subhead>
      <description>Sales report for the West Coast, Central and East Coast regions.</description>
   </summary>
   <data>
      <region>
         <name>West Coast</name>
         <quarter number="1" books_sold="24000" />
         <quarter number="2" books_sold="38600" />
         <quarter number="3" books_sold="44030" />
         <quarter number="4" books_sold="21000" />
      </region>
      <region>
         <name>Central</name>
         <quarter number="1" books_sold="11000" />
         <quarter number="2" books_sold="16080" />
         <quarter number="3" books_sold="25000" />
         <quarter number="4" books_sold="29000" />
      </region>
      <region>
         <name>East Coast</name>
         <quarter number="1" books_sold="27000" />
         <quarter number="2" books_sold="31400" />
         <quarter number="3" books_sold="40100" />
         <quarter number="4" books_sold="30000" />
      </region>
   </data>
</sales>
  3. In the folder that you created in Step 1, save the file as Sales.xml. You can leave the file open.
  4. In Windows Explorer, locate and then double-click on the Sales.xml file to view the file in Internet Explorer.

    Internet Explorer shows the file as an unformatted XML listing. This is the default display for Internet Explorer when viewing an XML file.

In the next lesson, Lesson 2: Using XPath Pattern Matching to Transform Elements, you create the XML style sheet that produces an HTML-formatted sales report from this data.


Lesson 2: Using XPath Pattern Matching to Transform Elements

We can make the display more readable than the default tree view in Internet Explorer by creating a new XSLT file, Transform.xsl, that transforms the heading data in the Sales.xml file into a presentable format. The XSLT file produces a new file that selectively includes data from the XML input file. Each piece of data from the XML input file is pulled into an appropriate HTML tag as defined by the XSLT file.

To create the Transform.xsl file

  1. In your HTML or text editor, create a new file and copy the following code into that file.
    <?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="//summary/heading"/></title>
</head>
<body>
<h1><xsl:value-of select="//summary/heading"/></h1>
<h2><xsl:value-of select="//summary/subhead"/></h2>
<p><xsl:value-of select="//summary/description"/></p>
</body>
</html>
</xsl:template>

</xsl:stylesheet>
  2. In the same folder that you saved the Sales.xml file, save the current file as Transform.xsl.

To specify the XSLT file to use with the XML file

  1. In your HTML or text editor, open the Sales.xml file (if not already opened).
  2. Locate the following code:
    <?xml version="1.0"?>
  3. After this line, add the following code:
    <?xml-stylesheet type="text/xsl" href="transform.xsl"?>

    This processing instruction identifies Transform.xsl as the XSLT file to be used for transforming Sales.xml.

  4. Save and close Sales.xml.

To view the transformed XML file

  1. In Internet Explorer, press F5 to refresh Sales.xml and see how Transform.xsl formats the data in the <summary> element of Sales.xml.

    If you don't see the right result after checking your XML and XSLT files, you might need to adjust your installation. For more information, see Setting Up XSLT.

  2. (optional) If you installed the Internet Explorer Tools for Validating XML and Viewing XSLT Output, right-click in Internet Explorer and then click View XSL Output.

How the Transform Works

At the beginning of Transform.xsl, the xsl:stylesheet line tells Internet Explorer that Transform.xsl is an XSLT file and the xsl:output line tells the XSLT processor to produce HTML output rather than the default output method of "xml".

The xsl:value-of lines use the XPath expressions to direct the XSLT parser to locate specific data elements in the XML file. For instance, <xsl:value-of select="//summary/heading"/> directs the parser to look for the <heading> element contained in the <summary> element and then format the data in the <heading> element with an HTML <h1> tag.

In the next lesson, Lesson 3: Looping Using <xsl:for-each>, you learn how to transform the <data> element in the Sales.xml file.


Lesson 3: Looping Using <xsl:for-each>

The sales data in Sales.xml consists of three regions (West Coast, Central, and East Coast) with four quarters per region.

...
   <data>
      <region>
         <name>West Coast</name>
         <quarter number="1" books_sold="24000" />
         <quarter number="2" books_sold="38600" />
         <quarter number="3" books_sold="44030" />
         <quarter number="4" books_sold="21000" />
      </region>
      <region>
         <name>Central</name>
         <quarter number="1" books_sold="11000" />
         <quarter number="2" books_sold="16080" />
         <quarter number="3" books_sold="25000" />
         <quarter number="4" books_sold="29000" />
      </region>
      <region>
         <name>East Coast</name>
         <quarter number="1" books_sold="27000" />
         <quarter number="2" books_sold="31400" />
         <quarter number="3" books_sold="40100" />
         <quarter number="4" books_sold="30000" />
      </region>
   </data>
...

Because the <region> tag repeats, it is cumbersome to handle this type of data using the simple, global pattern matching method described in Lesson 2. Fortunately, XSLT offers a better approach.

Using XSLT, you can define the formatting for a repeating data structure (such as the <region> blocks in Sales.xml), look for each occurrence of that structure, and then apply the specified formatting to each occurrence. This approach allows you to define the formatting once, but apply it multiple times.

To format the <data> section into table cells

  1. Using your HTML or text editor, open Transform.xsl and locate the </BODY> line.
  2. Immediately above the </BODY> line, add the following code:
    <table>
<!-- create table heading row, filling in the
             quarter numbers from left to right -->
<tr>
   <th>Region\Quarter</th>
   <xsl:for-each select="//data/region[1]/quarter">
      <th>Q<xsl:value-of select="@number"/></th>
   </xsl:for-each>
   <th>Total</th>
</tr>

<!-- create a table body row for each quarter, for each region,
                  filling cells with the number of books sold -->
<xsl:for-each select="//data/region">
<tr>
   <th style="text-align:left"><xsl:value-of select="name"/></th>

   <xsl:for-each select="quarter">
      <td style="text-align:right">
         <xsl:value-of select="format-number(@books_sold,'###,###')"/>
      </td>
   </xsl:for-each>

   <td style="text-align:right;font-weight:bold;">
      <!-- total will go here -->
   </td>

</tr>
</xsl:for-each>

</table>
  3. Save Transform.xsl. You can leave this file open.

To view the transformation of the <data> element

  1. In Internet Explorer, press F5 to refresh Sales.xml.

    The new portion of the sales report should look like this:

  2. (optional) If you installed the Internet Explorer Tools for Validating XML and Viewing XSLT Output, right-click in Internet Explorer and then click View XSL Output to directly inspect the tagging of the output file that was produced by the XSL transformation.

How the Transform Works

Some of the new code added to Transform.xsl contains the same xsl:value-of statements discussed in Lesson 2. However, there is something new here as well—the xsl:for-each statements.

The first part of these new statements, xsl:for-each, tells the parser to do something every time it finds the pattern defined by the second part of the statement. For instance, the statement, <xsl:for-each select="//data/region[1]/quarter">, indicates that something should be done every time the parser finds the <quarter> element within the first <region> element.

The formatting statements that follow each xsl:for-each statement define exactly what the parser has to do when it encounters the specified pattern. To illustrate, the formatting statement that follows the above statement is <th>Q<xsl:value-of select="@number"/>. This formatting statement indicates that the parser needs to look inside the <quarter> element, get the value of the number attribute, and insert that value into the table header after the letter "Q".

In the next lesson, Lesson 4: Summing Data, you learn how to use XSLT to summarize data, not just format it.


Lesson 4: Summing Data

To use XSL to calculate total annual sales in each region, insert the XSLT sum() function as follows:

To calculate total annual sales per region

  1. In your HTML or text editor, open Transform.xsl and delete the following line:
    <!-- total will go here -->
  2. Replace the deleted line with the following code:
    <xsl:value-of select="format-number(sum(quarter/@books_sold),'###,###')"/>
  3. Save and close Transform.xsl.

To view the summarized data

  1. In Internet Explorer, press F5 to refresh the display of Sales.xml. The Total column now shows the total number of books sold for the year per each region:

How the Function Works

The sum(quarter/@books_sold) function returns the sum of the data values for the books_sold attribute within all the <quarter> elements in the current context. The current context is the current <region> element, as defined by the XPath expression //data/region at the start of the outer loop.

In the next lesson, Lesson 5: Adding a Conditional Statement, you use conditional statements to compare whether or not each sales region met its sales goal figure.


Lesson 5: Adding a Conditional Statement

A conditional statement checks a piece of data and takes any of several actions based on its value.

In the following procedure, you define a quarterly sales goal and then use a conditional statement to see if the sales amount is greater or less than the goal. Figures less than or equal to the sales goal appear in red; figures greater than the sales goal appear in green.

To add conditional statements

  1. In your HTML or text editor, open Transform.xsl and locate the following line:
    <xsl:output method="html"/>
  2. Immediately below this line, add the following code:
    <xsl:param name="low_sales" select="21000"/>

    This creates a parameter variable named low_sales, which represents the sales goal, and assigns it the value of 21000. Now, you can insert the parameter variable low_sales whenever you want to refer to the sales goal. Setting a variable enables you to change the value of the variable in one place and update its value consistently throughout the file.

  3. Find and delete the following code:
    <td style="text-align:right">
   <xsl:value-of select="format-number(@books_sold,'###,###')"/>
</td>
  4. Replace it with the following code:
    <td>
   <xsl:attribute name="style">
      <xsl:choose>
         <xsl:when test="number(@books_sold &lt;= $low_sales)">
               color:red;</xsl:when>
         <xsl:otherwise>color:green;</xsl:otherwise>
      </xsl:choose>
      text-align:right;
   </xsl:attribute>
   <xsl:value-of select="format-number(@books_sold,'###,###')"/>
</td>
  5. Save Transform.xsl. You can leave the file open.

To view the conditionalized data

  1. In Internet Explorer, press F5 to refresh the display of Sales.xml. The page now looks like this:

    Note To change how the page appears, you can change the value assigned to the low_sales variable. For example, change the variable from 21000 to 31000 and save Transform.xls. Return to Internet Explorer and click Refresh to see how the page changes.

How the Conditional Statement Works

The code that you just added to Transform.xsl uses a combination of the <xsl:choose>, <xsl:when>, and <xsl:when> elements to form a conditional situation.

      <xsl:choose>
         <xsl:when test="number(@books_sold &lt;= $low_sales)">
               color:red;</xsl:when>
         <xsl:otherwise>color:green;</xsl:otherwise>
      </xsl:choose>

The <xsl:choose> element tells the parser that a conditional statement is coming. That conditional statement, <xsl:when test="number(@books_sold &lt;= $low_sales)">color:red;</xsl:when>, indicates that the parser needs to compare the value of the books_sold attribute in the <quarter> tag to the value of the low_sales variable. When the books_sold value is less than or equal to the low_sales value, then color the output as red. If the books_sold value is greater than the low_sales value, then the next statement, <xsl:otherwise>color:green;</xsl:otherwise>, sets the output color to green instead of red.

Also, notice that the style sheet property that controls the alignment of the column data has been moved into the definition for the style attribute, after the </xsl:choose> tag. This ensures that all of the style attributes are contained in the same style attribute.

In the next lesson, Lesson 6: Extracting Data from Other Documents, you learn how to include data from a file that contains a watermark and a copyright notice.


Lesson 6: Extracting Data from Other Documents

You can incorporate XML from external documents using the document() function. This function takes as an argument either the relative or absolute Uniform Resource Locater (URL) of the document you want to retrieve. The URL is specified as a string or as a node in which the text value of that node resolves to a URL. With document(), you load the entire contents of the document, and then select elements from the document by using XML Path Language (XPath) expressions.

In this tutorial, first you need to create the external document, Ancillary.xml, that contains a watermark and a copyright notice for the sales report. Then, you have to add the code to Transform.xsl that retrieves the Ancillary.xml file and formats that file's data.

To create Ancillary.xml

  1. In your HTML or text editor, open a new, empty file.
  2. Add the following code to the file:
    <?xml version='1.0'?>
<document>
   <watermark>Scootney Publishing</watermark>
   <copyright>Copyright 2000, Scootney Publishing. All Rights Reserved.</copyright>
</document>
  3. In the same folder as Sales.xml, save the file as Ancillary.xml and then close the file.

To update Transform.xsl to extract data from Ancillary.xml

  1. In your HTML or text editor, open Transform.xsl and locate the <BODY> line.
  2. Immediately below the <BODY> line add the following code:
    <xsl:variable name="ancillary" select="document('ancillary.xml')"/>

    This loads the Ancillary.xml document into the variable named ancillary.

  3. Directly below the line that you just added, add the following code:
    <div style="position:absolute;font-size:96;font-family:Times New Roman;
      color:#F0F0F0;z-index:-1">
   <xsl:value-of select="$ancillary//watermark"/>
</div>

    This code reads the watermark element from Ancillary.xml and formats the string it contains as a watermark. The XPath expression, $ancillary//watermark, resolves to all <watermark> elements in the Ancillary.xml file.

  4. Immediately above the </BODY> tag add the following code:
    <div style="font-size:9">
   <xsl:value-of select="$ancillary//copyright"/>
</div>

    These lines insert and format the copyright notice string from Ancillary.xml.

  5. Save Transform.xsl.

To view the main and ancillary

  1. In Internet Explorer, press F5 to refresh the display of Sales.xml. The page now looks like this:

This concludes the XSLT tutorial.


Final Files Produced in the XSLT Tutorial

When you finish the tutorial, the directory you created contains the following files.

  • XML Input Data File for the XSLT Tutorial
  • Transformation File for the XSLT Tutorial
  • Output File for the XSLT Tutorial
  • Ancillary.xml is shown below.

Ancillary.xml

<?xml version='1.0'?>
<document>
   <watermark>Scootney Publishing</watermark>
   <copyright>Copyright 2000, Scootney Publishing. All Rights Reserved.</copyright>
</document>


XML Input Data File for the XSLT Tutorial

When you finish the tutorial, Sales.xml is as follows:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="transform.xsl"?>
<sales>
   <summary>
      <heading>Scootney Publishing</heading>
      <subhead>Regional Sales Report</subhead>
      <description>Sales report for the West Coast, Central and East Coast regions.</description>
   </summary>
   <data>
      <region>
         <name>West Coast</name>
         <quarter number="1" books_sold="24000" />
         <quarter number="2" books_sold="38600" />
         <quarter number="3" books_sold="44030" />
         <quarter number="4" books_sold="21000" />
      </region>
      <region>
         <name>Central</name>
         <quarter number="1" books_sold="11000" />
         <quarter number="2" books_sold="16080" />
         <quarter number="3" books_sold="25000" />
         <quarter number="4" books_sold="29000" />
      </region>
      <region>
         <name>East Coast</name>
         <quarter number="1" books_sold="27000" />
         <quarter number="2" books_sold="31400" />
         <quarter number="3" books_sold="40100" />
         <quarter number="4" books_sold="30000" />
      </region>
   </data>
</sales>


Transformation File for the XSLT Tutorial

When you finish the tutorial, Transform.xsl is as follows:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:param name="low_sales" select="21000"/>

<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="//summary/heading"/></title>
</head>
<body>
<xsl:variable name="ancillary" select="document('ancillary.xml')"/>
<div style="position:absolute;font-size:96;font-family:Times New Roman;
      color:#F0F0F0;z-index:-1">
   <xsl:value-of select="$ancillary//watermark"/>
</div>
<h1><xsl:value-of select="//summary/heading"/></h1>
<h2><xsl:value-of select="//summary/subhead"/></h2>
<p><xsl:value-of select="//summary/description"/></p>
<table>
<!-- create table heading row, filling in the
             quarter numbers from left to right -->
<tr>
   <th>Region\Quarter</th>
   <xsl:for-each select="//data/region[1]/quarter">
      <th>Q<xsl:value-of select="@number"/></th>
   </xsl:for-each>
   <th>Total</th>
</tr>

<!-- create a table body row for each quarter, for each region,
                  filling cells with the number of books sold -->
<xsl:for-each select="//data/region">
<tr>
   <th style="text-align:left"><xsl:value-of select="name"/></th>

   <xsl:for-each select="quarter">
<td>
   <xsl:attribute name="style">
      <xsl:choose>
         <xsl:when test="number(@books_sold &lt;= $low_sales)">
               color:red;</xsl:when>
         <xsl:otherwise>color:green;</xsl:otherwise>
      </xsl:choose>
      text-align:right;
   </xsl:attribute>
   <xsl:value-of select="format-number(@books_sold,'###,###')"/>
</td>
   </xsl:for-each>

   <td style="text-align:right;font-weight:bold;">
      <xsl:value-of select="format-number(sum(quarter/@books_sold),'###,###')"/>
   </td>

</tr>
</xsl:for-each>

</table>
<div style="font-size:9">
   <xsl:value-of select="$ancillary//copyright"/>
</div>
</body>
</html>
</xsl:template>

</xsl:stylesheet>


Output File for the XSLT Tutorial

The complete file produced as output from the XSLT processor is shown here. To view this file after you finished the tutorial:

  1. View Sales.xml in Internet Explorer.
  2. If you installed the Internet Explorer Tools for Validating XML and Viewing XSLT Output, right-click in Internet Explorer and then click View XSL Output.
    <html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-16">
<title>Scootney Publishing</title>
</head>
<body>
<div style="position:absolute;font-size:96;font-family:Times New Roman;color:#F0F0F0;z-index:-1">Scootney Publishing</div>
<h1>Scootney Publishing</h1>
<h2>Regional Sales Report</h2>
<p>Sales report for the West Coast, Central and East Coast regions.</p>
<table>
<tr>
<th>Region\Quarter</th>
<th>Q1</th>
<th>Q2</th>
<th>Q3</th>
<th>Q4</th>
<th>Total</th>
</tr>
<tr>
<th style="text-align:left">West Coast</th>
<td style="color:green;
      text-align:right;
   ">24,000</td>
<td style="color:green;
      text-align:right;
   ">38,600</td>
<td style="color:green;
      text-align:right;
   ">44,030</td>
<td style="color:red;
      text-align:right;
   ">21,000</td>
<td style="text-align:right;font-weight:bold;">127,630</td>
</tr>
<tr>
<th style="text-align:left">Central</th>
<td style="color:red;
      text-align:right;
   ">11,000</td>
<td style="color:red;
      text-align:right;
   ">16,080</td>
<td style="color:green;
      text-align:right;
   ">25,000</td>
<td style="color:green;
      text-align:right;
   ">29,000</td>
<td style="text-align:right;font-weight:bold;">81,080</td>
</tr>
<tr>
<th style="text-align:left">East Coast</th>
<td style="color:green;
      text-align:right;
   ">27,000</td>
<td style="color:green;
      text-align:right;
   ">31,400</td>
<td style="color:green;
      text-align:right;
   ">40,100</td>
<td style="color:green;
      text-align:right;
   ">30,000</td>
<td style="text-align:right;font-weight:bold;">128,500</td>
</tr>
</table>
<div style="font-size:9">Copyright 2000, Scootney Publishing. All Rights Reserved.</div>
</body>
</html>


XSLT Utilities and Samples You Can Download

Microsoft provides the following utilities, samples, and documentation, available for download from MSDN®.

Other Resources Other Resources

XSLT Samples Viewer
This is an interactive, easy way to see a working example of each Extensible Stylesheet Language Transformations (XSLT) element and function. For each element or function, the viewer provides a common XML document and an XSLT file. To see the results of applying the XSLT file to the document, just click the Result button in the viewer.
Internet Explorer Tools for Validating XML and Viewing XSLT Output
Installing this tool adds the View XSL Output and Validate XML commands to the right-click menu of Microsoft® Internet Explorer. The View XSL Output command enables you to view the output tagging produced by an Extensible Stylesheet Language (XSL) or XSLT file. The Validate XML command enables you to validate XML against an embedded schema when loading XML using the Internet Explorer MIME viewer.
MSXSL.EXE Command Line Utility
Unlike hard coding an XSLT file name in an XML file, this utility enables you to specify any combination of XML and XSLT files at the command line and invoke the Microsoft XML Parser (MSXML 4.0) to perform the transformation.
XSLT Code Samples on MSDN
These samples show some of the ways that you can use XSLT to dynamically transform XML content.
XSL Code Samples on MSDN
These samples show some of the ways that you can use XSL to dynamically transform XML content.
XSL to XSLT Converter 1.1
This tool converts the XSL files included with Microsoft Internet Explorer 5.0 to XSLT-compliant files.
XSL Documentation for MSXML 2.5
Since MSXML 4.0 fully supports XSLT, the documentation that comes with this release is specific to XSLT not XSL. If you want to develop XSL files instead of XSLT files, download the MSXML 2.5 SDK for XSL-specific information.
XSL Debugger
This simple HTML-based debugger allows single-stepping through the execution of an XSL file. The debugger identifies the current positions in both the XSL file and XML documents. You can also set and clear breakpoints.


Frequently Asked Questions about XSLT

The following list includes frequently asked questions about Extensible Stylesheet Language Transformations (XSLT).

Why do my transformations fail using Internet Explorer?

How do I run XSLT transformations automatically from code?

Do I need to use a different XSLT namespace with Internet Explorer?

I have installed the Microsoft® XML Parser (MSXML 4.0). Why isn't my application using it?

Does MSXML 4.0 provide a 100% compliant XSLT processor?

Does Internet Explorer 5.5 include a fully compliant XSLT processor?

Is MSXML 4.0 a production version?

Why was the MSDN online documentation for XSL so different from the XSLT specification?

Where can I find documentation about the compliance of MSXML?

How can I call MSXML from the command prompt to do batch processing of XSLT?

What can I do if I wrote lots of XSL using the old Internet Explorer version of XSL?

Why do my transformations fail using Internet Explorer?

At the time of the release of Microsoft Internet Explorer 5.0 in 1998, there was only a working draft for the Extensible Stylesheet Language (XSL). There was no XSLT recommendation. Thus, the version of MSXML included in Internet Explorer only works with XSL.

Although there is now a final XSLT recommendation, there are still computers which have a version of MSXML installed that does not support XSLT. As a result, it is common for people to send feedback to Microsoft asking for information about why an XSLT operation does not work in Internet Explorer 5.0. Many people do not realize that their version of Internet Explorer uses a version of MSXML based on XSL, not XSLT.

If your XSLT transforms fail in Internet Explorer 5.0 (or later), you should install MSXML 4.0, the most current version of the MSXML parser, on your computer. For instructions on installing MSXML 4.0, see Installing MSXML 4.0 for XSLT Support.

Return to top

How do I run XSLT transformations automatically from code?

You can run an XSLT transformation on an XML document programmatically using code written in Microsoft JScript®, Microsoft Visual Basic® Scripting Edition (VBScript), Microsoft Visual Basic, C++, or any other language that supports COM, including Perl.

The following Visual Basic code calls a transformation against MSXML 4.0. This code sample uses the CreateObject("MSXML2.DOMDocument") syntax instead of the CreateObject("MSXML.DOMDocument") syntax associated with versions 2.x of MSXML. Using "MSXML2" ensures that you call the most current XSLT processor, not the 1998 working draft version. This example also shows you how to get detailed error information if your transformation fails. If you transform unstructured (non-XML) data, set xmlSource.ValidateOnParse=False instead of xmlSource.ValidateOnParse=True, as it appears in the following example. This step helps avoid an error caused by data not being well-formed.

        Dim xmlSource As Object
        Dim xmlXForm As Object
        Set xmlSource = CreateObject("Msxml2.DOMDocument")
        Set xmlXForm = CreateObject("Msxml2.DOMDocument")

        xmlSource.validateOnParse = True
        xmlXForm.validateOnParse = True
        xmlSource.async = False
        xmlXForm.async = False

        xmlSource.loadXML Text3.Text   ' This loads the text that I want _
          to transform
        If Err.Number <> 0 Then
            strErr = Err.Description & vbCrLf
            strErr = strErr & xmlSource.parseError.reason & " line: " & _
              xmlSource.parseError.Line & " col: " & _
              xmlSource.parseError.linepos & " text: " & _
              xmlSource.parseError.srcText
            MsgBox strErr, vbCritical, "Error loading the XML"
            GoTo bail
        End If

        xmlXForm.loadXML Text1.Text   ' This loads the XSLT transform
        If Err.Number <> 0 Then
            strErr = Err.Description & vbCrLf
            strErr = strErr & xmlSource.parseError.reason & " line: " & _
              xmlSource.parseError.Line & " col: " & _
              xmlSource.parseError.linepos & " text: " & _
              xmlSource.parseError.srcText
            MsgBox strErr, vbCritical, "Error loading the Transform"
            GoTo bail
        End If

        Text2.Text = xmlSource.transformNode(xmlXForm)  'This transforms _
          the data in xmlSource
        If Err.Number <> 0 Then
            strErr = Err.Description & vbCrLf
            strErr = strErr & xmlSource.parseError.reason & " line: " & _
              xmlSource.parseError.Line & " col: " & _
              xmlSource.parseError.linepos & " text: " & _
              xmlSource.parseError.srcText
            MsgBox strErr, vbCritical, "Error executing the Transform"
            GoTo bail
        End If

        Set xmlSource = Nothing
        Set xmlXForm = Nothing

Return to top

xmconDisplayingXMLFilesinInternetExplorerxmconInstallingMSXML30InReplaceMode!href(http://msdn.microsoft.com/downloads/default.asp?URL=/code/topic.asp?URL=/msdn-files/028/000/072/topic.xml)xmconDeployingXSLTOnInternetExplorer

xmconFrequentlyAskedQuestionsaboutXSLT

Do I need to use a different XSLT namespace with Internet Explorer?

No. Use the standard xmlns:xsl="http://www.w3.org/1999/XSL/Transform" syntax. If Internet Explorer returns an error when you use this namespace, it is likely that you are using an earlier version of MSXML that does not support XSLT. If you have older XSL files and do not want to convert them to XSLT files, you can still use the namespace declaration xmlns:xsl="http://www.w3.org/TR/WD-xsl". To convert XSL files to XSLT files, use the XSL to XSLT Converter 1.1 available from MSDN Online Downloads.

Return to top

I have installed the Microsoft XML parser (MSXML 4.0). Why isn't my application using it?

If you call your transformation from a programming language, it's likely that you are not using the correct ProgID. You must use the version-dependent ProgID. The following Microsoft Visual Basic code shows the correct syntax to create a DOMDocument object into which you load an XSLT file.

Visual Basic using the version-dependent ProgID

Dim xsltDoc
Set xsltDoc = CreateObject("Msxml2.DOMDocument.4.0")

For more information about ProgIDs and syntax, see GUID and ProgID Information. For more information about creating the DOMDocument object, see Using DOMDocument.

Return to top

Does MSXML 4.0 provide a 100% compliant XSLT processor?

Unlike versions prior to MSXML 3.0, the XSLT processor in MSXML 4.0 is highly compliant with the XSLT specification. For more information, see the Supported XSLT Features.

Return to top

Does Internet Explorer 5.5 include a fully compliant XSLT processor?

No. Microsoft Internet Explorer 5.5 includes a version of MSXML that does not offer XSLT support.

Return to top

Is MSXML 4.0 a production version?

No. It is a Technology Preview. MSXML 3.0 is the latest production version.

Return to top

Why was the MSDN online documentation for XSL so different from the XSLT recommendation?

At the time of this writing, the MSDN® online documentation contains information related to MSXML version 2.5, which features XSL functionality, not the XSLT functionality included in MSXML 4.0. There will be an update to the MSXML documentation on MSDN shortly after the production release of MSXML 4.0. Note that you can download the MSXML 4.0 SDK, which contains the MSXML 4.0 documentation, from the XML Developer Center at MSDN.microsoft.com/xml. The documentation is installed in C:\Program Files\Microsoft XML Parser SDK\Docs\xmlsdk40.chm on your hard drive. To view the documentation, which includes full disclosure about levels of conformance, double-click xmlsdk40.chm. For more information about conformance, see Supported XSLT Features.

Return to top

Where can I find documentation about compliance of MSXML?

Each new release of MSXML has a Bug List Page describing known problems, such as coding mistakes or features that are not fully implemented. For full conformance disclosure, see Supported XSLT Features. If you find a bug or implementation point that is not clearly documented, please send feedback to the XML documentation team by using the XML Documentation Feedback form. To use this form, click the Feedback icon (the envelope) at the top-right corner of any page of this documentation.

Return to top

How can I call MSXML from the command prompt to do batch processing of XSLT?

Because MSXML is a COM object, you can write VBScript, JScript, or other Microsoft Windows Scripting Host (WSH) files to launch MSXML from the command prompt. Microsoft provides an XSLT Command Line Utility, MSXSL.EXE, that performs command-line XSL transformations using the Microsoft XSL processor. MSXSL.EXE is a small (~11K) command-line utility that invokes MSXML4.DLL to perform the actual work of the transformation. MSXSL.EXE is available for download at the XML Developer Center at MSDN.microsoft.com/xml.

Return to top

What can I do if I wrote lots of XSL using the old Internet Explorer version of XSL?

If you would like to upgrade XSL files so that they are compliant with the XSLT recommendation, you can use the XSL to XSLT 1.1 Converter available from MSDN Online Downloads.

Return to top


Supported XSLT Features

The Microsoft® XML Parser (MSXML 4.0) fully supports the Extensible Stylesheet Language Transformations (XSLT) and XML Path Language (XPath) version 1.0 World Wide Web Consortium (W3C) recommendations. In addition, MSXML maintains backward compatibility with the MSXML 2.0 and 2.5 implementations of Section 2 of the December 1998 XSL Working Draft of the Extensible Stylesheet Language (XSL). There is no support for XSL formatting objects.

Note For information about support for XSL, see the XML SDK 2.5 documentation available at MSDN®.

MSXML bases its implementation on the XSL Transformations (XSLT) Version 1.0, W3C Recommendation 16 November 16 1999, and the XML Path Language (XPath) Version 1.0, W3C Recommendation 16 November 1999.

Where the XSLT recommendation provides a fallback behavior in cases of error (for example, two matching templates with the same priority), MSXML performs the fallback behavior.

MSXML provides two mechanisms for implementing extension functions, embedded script implementations (<msxsl:script>) and external objects (addObject). MSXML does not provide a mechanism for implementing extension elements.

With the release of MSXML 3.0, MSXML achieved full support of XSLT. As with this previous release, MSXML 4.0 closely complies with the W3C XSLT standard, save only in those areas, such as the use of the XML Linking Language (XLink) and XML Pointer Language (XPointer), where a formal W3C Recommendation has not yet been made. Close conformance means that XSLT file used elsewhere can also be deployed within MSXML 4.0, so long as these files also abide by this standard.

See Also

addObject Method | msxsl:script Element | Forwards-compatible Processing to Support Future Versions

Other Resources Other Resources

XML SDK 2.5 Documentation | XSL Transformations (XSLT) Version 1.0 | XML Path Language (XPath) Version 1.0


Template-Driven Transformations

An XSL Transformations (XSLT) transformation results in the creation of a new XML tree. This clear separation between the source document and the result trees fulfills the goal of XML to separate content from presentation by allowing both the grammar and structure of the XML source to be independent of the presentation language and structure.

Used in the simplest way, XSLT provides a capability similar to a "mail merge." The style sheet contains a template of the desired result structure, and identifies data in the source document to insert into this template. This model for merging data and templates is referred to as the template-driven model and works well on regular and repetitive data. This model will be familiar to users of Active Server Pages (ASPs), which embed bits of script within an HTML template to control processing and insert data. The Microsoft® Internet Explorer data binding features also use a template-driven model—elements in the HTML page provide templates for displaying bound data.

XSLT also provides capabilities for handling highly irregular and recursive data, as is typical in documents. Template fragments are defined, and the XSLT processor combines the results of these fragments into a final result tree based on the shape of the source data. Each template fragment declares the type and context of source nodes it is appropriate for, allowing the XSLT processor to match source nodes with template fragments. This model is known as the data-driven model because the shape of the data drives the shape of the final output.

Template-driven and data-driven transformation mechanisms can be combined in a single style sheet, making XSLT appropriate to a wide variety of XML applications.

This section covers the following:

  • Creating and Populating an HTML Template
  • Generating Well-Formed HTML Using XSLT
  • Selecting and Outputting Attributes
  • Sorting XML Using <xsl:sort>
  • Defining Conditional Templates Using <xsl:if> and <xsl:choose>

See Also

Using XPath Expressions to Select Nodes | Getting Started with XSLT | Data-Driven Transformations


Creating and Populating an HTML Template

You can use XSL Transformations (XSLT) to merge simple regular XML data with an HTML template for display. Consider the XML data in portfolio.xml in the example below. The structure of this sample data is repetitive and regular—the stock element structure is repeated several times with the same child elements. For this example, the stock information will be displayed in a table with a stock in each row, and cells containing the name, symbol, and price. First create a template of HTML elements to display such a table.

<HTML>
  <BODY>
    <TABLE BORDER="2">
      <TR>
        <TD>Symbol</TD>
        <TD>Name</TD>
        <TD>Price</TD>
      </TR>
      <!-- repeat the following row for each stock -->
      <TR>
        <TD><!-- symbol goes here --></TD>
        <TD><!-- name goes here --></TD>
        <TD><!-- price goes here --></TD>
      </TR>
    </TABLE>
  </BODY>
</HTML>

To populate the above template with data from the XML file, you could manually replace the comments with data from the XML file, which is essentially the process that the XSLT performs. To perform this replacement using XSLT, elements from the XSLT namespace (such as <xsl:value-of>) are used with XPath expressions to locate data in the XML file, and insert it into the HTML template. The following XSLT fragment would achieve the same as the above manual replacement:

<HTML>
  <BODY>
    <TABLE BORDER="2">
      <TR>
        <TD>Symbol</TD>
        <TD>Name</TD>
        <TD>Price</TD>
      </TR>
      <xsl:for-each select="portfolio/stock">
        <TR>
          <TD><xsl:value-of select="symbol"/></TD>
          <TD><xsl:value-of select="name"/></TD>
          <TD><xsl:value-of select="price"/></TD>
        </TR>
      </xsl:for-each>
    </TABLE>
  </BODY>
</HTML>

The <xsl:for-each> element locates a set of elements in the XML data ("stock" elements inside the "portfolio" element) and repeats a portion of the template for each one. Because this sample contains three stock elements, three rows will be created.

The select attribute describes how to find a set of elements in the source document. The syntax for this attribute is called a pattern, and works much like navigating a file system hierarchy where a forward slash (/) selects subdirectories relative to the current directory. In an XSLT style sheet, the navigation starts at the current node and drills down into the XML data hierarchy, selecting all the nodes that match the pattern. In this case the pattern "portfolio/stock" starts at the document root and drills down through the "portfolio" element to select the three "stock" children.

For many style sheets, the use of element names and the / operator is sufficiently powerful to perform the desired transformation. For information about other XSLT operations, see Introduction to XPath Syntax.

Within the <xsl:for-each> element, you can further drill down to select children of each "stock" element. The <xsl:value-of> element selects a specific child and then inserts the text content of that child into the template. The patterns inside the <xsl:value-of> element's select attribute do not require starting at the document root again but are relative to the element selected in the <xsl:for-each> element.

The preceding template can be made into a complete XSLT style sheet by placing it in an XML file and enclosing it within the <xsl:stylesheet> element, as shown in the sample XSLT file below.

Because a style sheet is an XML file itself, the resulting XSLT file begins with the recommended XML declaration. The <xsl:stylesheet> element indicates that the XSLT document is a style sheet file, and provides a location for declaring the XSLT namespace. Microsoft® Internet Explorer 5.0 supports the XSL namespace URL http://www.w3.org/TR/WD-xsl. The current Microsoft XML Parser (MSXML) supports both the XSL namespace URL http://www.w3.org/TR/WD-xsl and the XSLT namespace URL http://www.w3.org/1999/XSL/Transform.

You also must wrap the template with <xsl:template match="/"> to indicate that this template corresponds to the root (/) of the XML source document. For more information, see Defining Match Patterns in <xsl:template>.

The entire XSLT file, including the HTML that comprises the template, must be well-formed. For more information about authoring or converting to well-formed HTML, see Generating Well-Formed HTML Using XSLT.

Example

To display the data from portfolio-dataonly.xml in a Web browser using portfolio.xsl, you must add a processing instruction to the XML file to indicate that a style sheet is to be used. The following XML file, portfolio.xml, shows this instruction, <?xml-stylesheet type="text/xsl" href="portfolio.xsl"?> and can therefore be displayed in Internet Explorer.

The XSLT processor output listing shows how the basic transformation mechanism combines the template defined in the XSLT file with data from the source XML document to create a final result as a text stream.

XML File (portfolio.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="portfolio.xsl"?>
<portfolio xmlns:dt="urn:schemas-microsoft-com:datatypes" xml:space="preserve">
  <stock exchange="nyse">
    <name>zacx corp</name>
    <symbol>ZCXM</symbol>
    <price dt:dt="number">28.875</price>
  </stock>
  <stock exchange="nasdaq">
    <name>zaffymat inc</name>
    <symbol>ZFFX</symbol>
    <price dt:dt="number">92.250</price>
  </stock>
  <stock exchange="nasdaq">
    <name>zysmergy inc</name>
    <symbol>ZYSZ</symbol>
    <price dt:dt="number">20.313</price>
  </stock>
</portfolio>

XSLT File (portfolio.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
    <HTML>
      <BODY>
        <TABLE BORDER="2">
          <TR>
            <TD>Symbol</TD>
            <TD>Name</TD>
            <TD>Price</TD>
          </TR>
          <xsl:for-each select="portfolio/stock">
            <TR>
              <TD><xsl:value-of select="symbol"/></TD>
              <TD><xsl:value-of select="name"/></TD>
              <TD><xsl:value-of select="price"/></TD>
            </TR>
          </xsl:for-each>
        </TABLE>
      </BODY>
    </HTML>
  </xsl:template>
</xsl:stylesheet>

XSLT Processor Output

<HTML>
  <BODY>
    <TABLE BORDER="2">
      <TR>
        <TD>Symbol</TD>
        <TD>Name</TD>
        <TD>Price</TD>
      </TR>
      <TR>
        <TD>ZCXM</TD>
        <TD>zacx corp</TD>
        <TD>28.875</TD>
      </TR>
      <TR>
        <TD>ZFFX</TD>
        <TD>zaffymat inc</TD>
        <TD>92.250</TD>
      </TR>
      <TR>
        <TD>ZYSZ</TD>
        <TD>zysmergy inc</TD>
        <TD>20.313</TD>
      </TR>
    </TABLE>
  </BODY>
</HTML>

Formatted Output


Generating Well-Formed HTML Using XSLT

Well-formed HTML simply means HTML that conforms to the rules of XML. This means that the same HTML tags are available, but the stricter XML syntax is required. An XSL Transformations (XSLT) style sheet is itself XML and any HTML within it must be well-formed.

In addition to HTML within an XSLT style sheet, you should consider authoring well-formed HTML for its own sake as well. The industry is moving toward well-formedness as a way to increase the robustness of the Web, while simplifying and accelerating the processing of well-formed documents and data. Well-formedness has great advantages for authoring tools and can benefit hand authoring by ensuring that the markup is unambiguous. The industry expectation is that a future HTML standard will be an XML application.

The price for these benefits is that a less forgiving syntax must be used.

Writing well-formed HTML is simple. Here are the basic rules to follow as you author or convert to well-formed HTML.

All tags must be closed

HTML allows certain end tags to be optional, the most common being <P>, <LI>, <TR>, and <TD>. XML requires all tags to be closed explicitly.

HTML Well-formed HTML
<P> This is an HTML paragraph.

<P>or two.

<P>This is an HTML paragraph.</P>

<P>or two.</P>

Leaf nodes must also be closed by placing a forward slash (/) within the tag. The most common examples are <BR>, <HR>, <INPUT>, and <IMG>.

HTML Well-formed HTML
<IMG src="sample.gif"

     width="10" height="20">

<IMG src="sample.gif"

     width="10" height="20" />

No overlapping tags

XML does not allow start and end tags to overlap, but enforces a strict hierarchy within the document.

HTML Well-formed HTML
<B>Well <I>Hello</B> Dolly!</I>

<B>Well</B> <I><B>Hello</B> Dolly!</I>

Case matters

Choose a consistent case for start and end tags. The examples generally use uppercase for HTML elements.

HTML Well-formed HTML
<B><i>Hello Dolly!</I></b>

<B><I>Hello Dolly!</I></B>

Quote your attributes

All attributes must be surrounded by quotation marks, either single or double.

HTML Well-formed HTML
<IMG src=sample.gif

     width=10 height=20 >

<IMG src='sample.gif'

     width="10" height="20" />

Use a single root

Shortcuts that eliminate the <HTML> element as the single top-level element are not allowed.

HTML Well-formed HTML
<TITLE>Funky markup</TITLE>

<BODY>
  <P>Amazing that this HTML works.</P>
</BODY>

<HTML>

  <HEAD>
    <TITLE>Clean markup</TITLE>
  </HEAD>
  <BODY>
    <P>Not nearly so amazing that
    this well-formed HTML works.</P>
  </BODY>
</HTML>

Fewer built-in entities

XML defines only a minimal set of built-in character entities.

  • &lt; — (<)
  • &gt; — (>)
  • &amp; — (&)
  • &quot; — (")
  • &apos; — (')

Numeric character entities are supported.

For nonbreaking spaces, instead of using &nbsp;, use &#160; or &#xA0;.

Escape script blocks

Script blocks in HTML can contain unparseable characters, namely < and &. These must be escaped in well-formed HTML by using character entities, or by enclosing the script block in a CDATA section.

In addition, Microsoft® JScript® (compatible with ECMA 262 language specification) comments terminate at the end of the line, so preserving the white space within script blocks containing comments is important. By default, the xml:space attribute value normalizes white space by compressing adjacent white space characters into a single space. This destroys the new line that terminates the JScript comment. Any JScript following the comment is treated as part of the comment and ignored, often resulting in script errors. The CDATA notation also ensures that the white space is preserved.

The following HTML script block contains both an unparseable character (<) and JScript comments. The well-formed script block uses CDATA to encapsulate the script.

HTML Well-formed HTML
<SCRIPT>

  // checks a number against 7
  function less-than-seven(n) {
    return n < 7;
  }
</SCRIPT>

<SCRIPT><![CDATA[

  // checks a number against 7
  function less-than-seven(n) {
    return n < 7;
  }
]]></SCRIPT>

Not all scripts will fail if they are not escaped in this way. However, it is highly recommended that you do it as a matter of habit. This ensures not only that the script will work if it contains escaped characters or comments now, but will continue to work if these characters are added in the future.


Selecting and Outputting Attributes

XSL Transformations (XSLT) provides mechanisms for accessing attributes in the source document, and for generating attributes in the result tree. XSLT attempts to be agnostic about whether data should be encoded as attribute values or child elements, and strives to process either with equal ease.

Attributes in the source document can be accessed in a pattern by preceding the attribute name with the @ symbol. The following example extracts the value of the exchange attribute on stock elements and inserts it into the output. For more information about selecting attributes, see Using XPath Expressions to Select Nodes.

Attributes can be created in two ways—by placing them on an output element, such as the BORDER='2' attribute above, or by adding them to an element with the <xsl:attribute> element. <xsl:attribute> allows the output attribute's value to be generated from the source data.

The name attribute specifies the name for the output attribute, and the contents of the tag are evaluated to determine its value. In the preceding example, a TITLE attribute is added to the <TR> element to display a ToolTip generated by mixing text with element and attribute values from the source document.

Attributes can be added to an element that already has attributes directly specified on it, so you can mix direct specifications and <xsl:attribute> freely. Be aware of the following limitations.

  • You cannot add an attribute to an element that already has an attribute of that name.
  • Attributes added with <xsl:attribute> must appear before children are added to the element.

Example

XML File (portfolio-attributes.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="portfolio-attributes.xsl"?>
<portfolio xmlns:dt="urn:schemas-microsoft-com:datatypes" xml:space="preserve">
  <stock exchange="nyse">
    <name>zacx corp</name>
    <symbol>ZCXM</symbol>
    <price dt:dt="number">28.875</price>
  </stock>
  <stock exchange="nasdaq">
    <name>zaffymat inc</name>
    <symbol>ZFFX</symbol>
    <price dt:dt="number">92.250</price>
  </stock>
  <stock exchange="nasdaq">
    <name>zysmergy inc</name>
    <symbol>ZYSZ</symbol>
    <price dt:dt="number">20.313</price>
  </stock>
</portfolio>

XSLT File (portfolio-attributes.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
    <HTML>
      <BODY>
        <TABLE BORDER="2">
          <TR>
            <TD>Symbol</TD>
            <TD>Name</TD>
            <TD>Price</TD>
          </TR>
          <xsl:for-each select="portfolio/stock">
            <TR>
              <xsl:attribute name="TITLE"><xsl:value-of select="symbol"/>
                is listed on the <xsl:value-of select="@exchange"/>
                stock exchange.</xsl:attribute>
              <TD><xsl:value-of select="symbol"/></TD>
              <TD><xsl:value-of select="name"/></TD>
              <TD><xsl:value-of select="price"/></TD>
            </TR>
          </xsl:for-each>
        </TABLE>
      </BODY>
    </HTML>
  </xsl:template>
</xsl:stylesheet>

Formatted Output


Sorting XML Using <xsl:sort>

Sorting is specified by adding <xsl:sort> elements as children to an <xsl:apply-templates> or an <xsl:for-each> element. The first <xsl:sort> child specifies the primary sort key, the second <xsl:sort> child specifies the secondary sort key, and so on. When an <xsl:apply-templates> or <xsl:for-each> element has one or more <xsl:sort> children, instead of processing the selected nodes in document order, it sorts the nodes according to the specified sort keys and then processes them in sorted order. When used in <xsl:for-each>, <xsl:sort> elements must occur first. When a template is instantiated by <xsl:apply-templates> and <xsl:for-each>, the current node list consists of the complete list of nodes being processed in sorted order.

<xsl:sort> has a select attribute whose value is an expression. For each node to be processed, the expression is evaluated with that node as the current node and with the complete list of nodes being processed in unsorted order as the current node list. The resulting object is converted to a string; this string is used as the sort key for that node. The default value of the select attribute is ".", which will cause the string value of the current node to be used as the sort key.

This string serves as a sort key for the node. The following optional attributes on <xsl:sort> control how the list of sort keys are sorted.

order
Specifies whether the strings should be sorted in ascending or descending order. Ascending specifies ascending order; descending specifies descending order. The default is ascending.
data-type
Specifies the data type of the strings. The following values are allowed:

Text
Specifies that the sort keys should be sorted alphabetically. This is the default.

Number
Specifies that the sort keys should be converted to numbers and then sorted according to the numeric value. The sort key is converted to a number as if by a call to the function.

A qualified name with a prefix is expanded into an expanded name. The expanded name identifies the data type.

The sort must be stable: In the sorted list of nodes, any sub list that has sort keys that all compare equal must be in document order.

Suppose an employee database has the following form.

<employees>
  <employee>
    <name>
      <given>James</given>
      <family>Clark</family>
    </name>
    ...
  </employee>
</employees>

A complete XML file containing this data and a reference to the XSLT file is shown in the sample below.

Example

This sample sorts a list of employees by name.

XML File (sortempl.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="sortempl.xsl"?>
<employees>
  <employee>
    <name>
      <given>Jon</given>
      <family>Ott</family>
    </name>
  </employee>
  <employee>
    <name>
      <given>Albert</given>
      <family>Zinn</family>
    </name>
  </employee>
  <employee>
    <name>
      <given>James</given>
      <family>Clark</family>
    </name>
  </employee>
  <employee>
    <name>
      <given>Sasha</given>
      <family>Allegro</family>
    </name>
  </employee>
  <employee>
    <name>
      <given>Rick</given>
      <family>Allegro</family>
    </name>
  </employee>
  <employee>
    <name>
      <given>Gordon</given>
      <family>Allegro</family>
    </name>
  </employee>
</employees>

XSLT File (sortempl.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="employees">
  <ul>
    <xsl:apply-templates select="employee">
      <xsl:sort select="name/family"/>
      <xsl:sort select="name/given"/>
    </xsl:apply-templates>
  </ul>
</xsl:template>

<xsl:template match="employee">
  <li>
    <xsl:value-of select="name/given"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="name/family"/>
  </li>
</xsl:template>

</xsl:stylesheet>

Formatted Output

  • Gordon Allegro
  • Rick Allegro
  • Sasha Allegro
  • James Clark
  • Jon Ott
  • Albert Zinn

Interactive Example

To see an interactive sorting sample showing several sort orders, click the Portfolio Sample at XSLT Developer's Guide Samples. See the XSL version of this sample at XSL Developer's Guide Samples.

Then view sort.htm in Internet Explorer.

See Also

Qualified Names | Expressions

Other Resources Other Resources

XSLT Developer's Guide Samples | XSL Developer's Guide Samples


Defining Conditional Templates Using <xsl:if> and <xsl:choose>

Conditional templates are output only if certain conditions exist within the source document. Conditional templates are defined with the <xsl:if> and <xsl:choose> elements.

This section covers the following:

  • Defining Conditional Templates Using <xsl:if>
  • Defining Conditional Templates Using <xsl:choose>


Defining Conditional Templates Using <xsl:if>

In the portfolio data in the XML file in the example below, the "stock" element has an attribute named "exchange". You might want to generate some output only when this attribute has a certain value.

You can easily create another row in the table in which to place the attribute value, but suppose you want to indicate stocks from a particular exchange not by a completely new table row, but by noting them with an asterisk (*). The <xsl:if> element provides a mechanism for conditionally inserting structure into the output tree.

In the following example, the <xsl:if> element inserts an "*" after the symbol for those stocks listed on the NASDAQ stock exchange. The <xsl:if> contents can be simple text, as in this example, or any structure allowed by XSL Transformations (XSLT), such as elements or attributes.

In the sample XSLT file below, the test attribute takes a pattern. If the query described by the pattern selects one or more nodes, the <xsl:if> template is inserted. If the selection is empty, the conditional is skipped. In this case, the query checks to see if the <stock> element has an exchange attribute, and further checks that the value of the exchange attribute is equal to "nasdaq". For more information about qualifying a pattern using brackets ([]) and constructing patterns that compare values, see Introduction to XPath Syntax.

Example

XML File (portfolio-if.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="portfolio-if.xsl"?>
<portfolio xmlns:dt="urn:schemas-microsoft-com:datatypes" xml:space="preserve">
  <stock exchange="nyse">
    <name>zacx corp</name>
    <symbol>ZCXM</symbol>
    <price dt:dt="number">28.875</price>
  </stock>
  <stock exchange="nasdaq">
    <name>zaffymat inc</name>
    <symbol>ZFFX</symbol>
    <price dt:dt="number">92.250</price>
  </stock>
  <stock exchange="nasdaq">
    <name>zysmergy inc</name>
    <symbol>ZYSZ</symbol>
    <price dt:dt="number">20.313</price>
  </stock>
</portfolio>

XSLT File (portfolio-if.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
    <HTML>
      <BODY>
        <TABLE BORDER="2">
          <TR>
            <TD>Symbol</TD>
            <TD>Name</TD>
            <TD>Price</TD>
          </TR>
          <xsl:for-each select="portfolio/stock">
            <TR>
              <TD>
                <xsl:value-of select="symbol"/>
                <xsl:if test="@exchange[.='nasdaq']">*</xsl:if>
              </TD>
              <TD><xsl:value-of select="name"/></TD>
              <TD><xsl:value-of select="price"/></TD>
            </TR>
          </xsl:for-each>
        </TABLE>
        <P>* Listed on Nasdaq stock exchange</P>
      </BODY>
    </HTML>
  </xsl:template>
</xsl:stylesheet>

Formatted Output


Defining Conditional Templates Using <xsl:choose>

The <xsl:choose> element provides a mechanism for "either/or" processing. <xsl:choose> contains a series of <xsl:when> elements that are tested in order from top to bottom until a match is found. An <xsl:otherwise> element can be used to insert a template if no match is found.

The following code can be added to the preceding example to color-code the rows by price. 0-25 are displayed in green; 25-50 are displayed in blue; and 50+ are displayed in red. The color is changed by conditionally generating a portion of the value of the STYLE attribute on the table row.

<TR>
  <xsl:attribute name="STYLE">color:
    <xsl:choose>
      <xsl:when test="price[. &lt; 25]">green</xsl:when>
      <xsl:when test="price[. &lt; 50]">blue</xsl:when>
      <xsl:otherwise>red</xsl:otherwise>
    </xsl:choose>
  </xsl:attribute>
  <TD>

Example

XML File (portfolio-choose.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="portfolio-choose.xsl"?>
<portfolio xmlns:dt="urn:schemas-microsoft-com:datatypes" xml:space="preserve">
  <stock exchange="nyse">
    <name>zacx corp</name>
    <symbol>ZCXM</symbol>
    <price dt:dt="number">28.875</price>
  </stock>
  <stock exchange="nasdaq">
    <name>zaffymat inc</name>
    <symbol>ZFFX</symbol>
    <price dt:dt="number">92.250</price>
  </stock>
  <stock exchange="nasdaq">
    <name>zysmergy inc</name>
    <symbol>ZYSZ</symbol>
    <price dt:dt="number">20.313</price>
  </stock>
</portfolio>

XSLT File (portfolio-choose.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
    <HTML>
      <BODY>
        <TABLE BORDER="2">
          <TR>
            <TD>Symbol</TD>
            <TD>Name</TD>
            <TD>Price</TD>
          </TR>
          <xsl:for-each select="portfolio/stock">
            <TR>
              <xsl:attribute name="STYLE">color:
                <xsl:choose>
                  <xsl:when test="price[. &lt; 25]">green</xsl:when>
                  <xsl:when test="price[. &lt; 50]">blue</xsl:when>
                  <xsl:otherwise>red</xsl:otherwise>
                </xsl:choose>
              </xsl:attribute>
              <TD>
                <xsl:value-of select="symbol"/>
                <xsl:if test="@exchange[.='nasdaq']">*</xsl:if>
              </TD>
              <TD><xsl:value-of select="name"/></TD>
              <TD><xsl:value-of select="price"/></TD>
            </TR>
          </xsl:for-each>
        </TABLE>
        <P>* Listed on Nasdaq stock exchange</P>
        <P>Price key: <SPAN STYLE="color:green">less than 25</SPAN>,
            <SPAN STYLE="color:blue">25-50</SPAN>,
            <SPAN STYLE="color:red">50+</SPAN>.</P>
      </BODY>
    </HTML>
  </xsl:template>
</xsl:stylesheet>

Formatted Output


Displaying Transformation Results

This section covers the following:

  • Displaying XML Files in a Browser
  • Using the Default Style Sheet
  • Using an External Style Sheet
  • Using Cascading Style Sheets to Display Results
  • Using Namespaces with CSS
  • XSLT Requirements for Viewing XML in a Browser
  • Accessing XML and XSLT Documents from Script
  • Serving Out XML Files from an HTTP Server


Displaying XML Files in a Browser

You can use Microsoft® Internet Explorer 5.0 or later to view XML documents in the browser just as you would view HTML pages. Unlike HTML, XML does not predefine display properties for specific elements. Thus, XML requires a separate style sheet that specifies how the XML data should be displayed. This separation of XML content from its presentation allows the content to be easily repurposed.

To view an XML file in Internet Explorer, you can specify a style sheet the following ways:

  • Use the default style sheet, which presents the file as a collapsable tree
  • Specify a specific style sheet at the top of the XML file, in an href attribute: <?xml-stylesheet type="text/xsl" href="myfile.xsl" ?>.
  • Specify any style sheet at the command prompt: c:\bat\msxsl mydata.xml mytransform.xsl -o myoutput.html

See Also

Using the Default Style Sheet | Using an External Style Sheet | XSLT Utilities and Samples You Can Download


Using the Default Style Sheet

If an XML document does not contain a valid style sheet processing instruction, Microsoft® Internet Explorer 5.0 or later displays the XML as an expanding and collapsing tree.

This tree view of the XML data is a convenient way to check that your XML is well-formed. To check a document, simply open the file in Internet Explorer. If there are any errors caused by the XML data not being well-formed, Internet Explorer lists these errors, along with their line numbers, onscreen.

Tip You can also use Internet Explorer to check that your XSLT style sheets and XML Schema documents are well-formed.

Internet Explorer displays an XML document asynchronously. This means that it starts displaying the XML document before the document has been completely downloaded. If an error occurs toward the end of a long document, most of the document may already be onscreen before Internet Explorer inserts an error message. In this case, you may have to scroll to the bottom of the page to view the error message.

Note When displaying XML documents, Internet Explorer loads the specified document type definition (DTD) or XML Schema, but does not report validation errors.

See Also

Using an External Style Sheet | Debugging a Style Sheet | Debugging XSLT


Using an External Style Sheet

In addition to its default style sheet, Microsoft® Internet Explorer supports style sheets written as either cascading style sheets or Extensible Stylesheet Language Transformations (XSLT) files. To use one of these style sheets to display an XML document, you need to include a style sheet processing instruction in the XML document that indicates the type and location of the style sheet.

Note While Internet Explorer automatically uses the style sheet processing instruction to display XML directly in the browser, other uses of XML, such as data islands, ignore this instruction.

A style sheet processing instruction needs to be at the beginning of an XML document, following the XML declaration (if there is one) and the document-type declaration (if there is one), as shown in the following XML document.

<?xml version="1.0" ?>
<!DOCTYPE region >
<?xml-stylesheet type="text/css" href="region.css" ?>
<region>
<name>Western Region</name>
<quarter number="1" books_sold="24000"/>
<quarter number="2" books_sold="38600"/>
</region>

An XML document can include multiple style sheet processing instructions. Internet Explorer 5.0 looks first for a processing instruction of type text/xsl and uses the first one it finds. Otherwise, it searches for text/css processing instructions and cascades them together using the same process as the HTML <LINK> element. Other attributes that are allowed on the <LINK> element can also be specified in the style sheet processing instruction. These are either ignored in the case of XSLT or treated the same as corresponding elements on the HTML <LINK> element.

For the Worldwide Web Consortium (W3C) recommendation for style sheet processing instruction syntax, see http://www.w3.org/TR/xml-stylesheet.

See Also

Using the Default Style Sheet


Using Cascading Style Sheets to Display Results

For Web-based XML applications, it is often important not only to transform XML into HTML (a natural use of XSLT), but also to style the resulting HTML. An XSLT transformation can easily emit <font> elements, bgcolor attributes for <body> elements, and so on, just as easily as it can other HTML.

For a number of important reasons, though, your HTML code will benefit from using cascading style sheets to control a page's appearance and other presentation attributes. Luckily, combining XSLT's transformational strengths with cascading style sheet's style power is quite simple.

This section covers the following:

  • Incorporating <style> Elements into an XSLT File
  • Using an External Cascading Style Sheet

See Also

Comparing XSLT to Cascading Style Sheets | Using XSLT with Cascading Style Sheets


Incorporating <style> Elements into an XSLT File

One option is for the XSLT style sheet to emit HTML <style> elements, including CSS specifications, directly into the HTML resulting from the transformation. This option works best when the number of CSS rules is small and easily managed.

To place a <style> element and its CSS rules into the transformation's result tree, you can simply include them in the XSLT template which instantiates the HTML <head> element. A pair of template rules to do so, and to style the corresponding portion of the sample XML document, might look as shown in book.xsl below.

In the XSLT file, the first template rule matches on the document's root element, <book>. When it finds a match in the source tree, it instantiates <html> and <head> elements in the result tree, including for the latter both a <title> element and a <style> element. The <style> element includes a single CSS rule, which says to display all <h1> elements in the result tree in the indicated font. Finally, this template rule says to instantiate a <body> element and then to process any children of the template rule's matching <book> element (this is the purpose of the <xsl:apply-templates/> element), checking for other template rules which match them and transforming them as necessary.

The second template rule, invoked (after a fashion) by the first's <xsl:apply-templates/> element, instantiates an <h1> element whose content is that of a book_title element in the source tree.

The result of applying this transformation to the sample source document is shown below.

Example

XML File (book.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="book.xsl" ?>
<book>
    <book_title>Jambing on the Trixles</book_title>
    <author> Randall, Tristan</author>
</book>

XSLT File (book.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="book">
    <html>
<head>
            <title>Book Info</title>
        <style>
                h1 {font-family: Arial,Univers,sans-serif;
                    font-size: 36pt }
        </style>
    </head>
    <body><xsl:apply-templates/></body>
    </html>
</xsl:template>

<xsl:template match="book_title">
    <h1><xsl:value-of select="."/></h1>
</xsl:template>

</xsl:stylesheet>

XSLT Processor Output

<html>
<head>
        <title>Book Info</title>
        <style>
            h1 {font-family: Arial,Univers,sans-serif;
                font-size: 36pt }
        </style>
    </head>
    <body><h1>Jambing on the Trixles</h1></body>
</html>

Formatted Output

See Also

Using the <style> Element with Older Browsers


Using the <style> Element with Older Browsers

This section describes a "best practices" XSLT-to-HTML transformation. However, older browsers cannot process a client-side XSLT-to-HTML transformation, so this section applies to server-side or static transformations only.

Some browsers, particularly older ones, do not recognize the <style> element at all. As with any unrecognized HTML elements, the default behavior of such browsers is simply to display the unrecognized element's contents—in this case, the CSS code itself.

To prevent this behavior, in a standalone HTML document you would embed the CSS code in an HTML comment. This masks the CSS code from browsers incapable of understanding the <style> element, while still making it available to browsers which do understand the <style> element.

To create a comment in the result tree of an XSLT transformation, you use an <xsl:comment> element whose content is the text of the comment.

(Note that you cannot simply place the literal <!-- and --> comment delimiters in the result tree to create the desired effect. Doing so simply creates a comment in the XSLT style sheet itself.)

Thus, a backwards-compatible version of the template rule for processing the <book> element from book.xsl would now look like bookbackwcmp.xsl, shown below.

Example

XML File (bookbackwcmp.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="bookbackwcmp.xsl" ?>
<book>
    <book_title>Jambing on the Trixles</book_title>
    <author> Randall, Tristan</author>
</book>

XSLT File (bookbackwcmp.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="book">
    <html>
<head>
            <title>Book Info</title>
        <style>
            <xsl:comment>
                h1 {font-family: Arial,Univers,sans-serif;
                    font-size: 36pt }
                </xsl:comment>
            </style>
    </head>
    <body><xsl:apply-templates/></body>
    </html>
</xsl:template>

<xsl:template match="book_title">
    <h1><xsl:value-of select="."/></h1>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Jambing on the Trixles Randall, Tristan


Using an External Cascading Style Sheet

Simply instantiating a <style> element in the result tree is simple and effective for fairly small cascading style sheet rule sets. A better solution for larger blocks of CSS code is to place them in a separate, external CSS style sheet file, and then instantiate in the result tree an HTML <link> element which refers to the external file.

Assume the CSS style sheet is in a file called book.css. An XSLT template rule in bookextcss.xsl for processing the <book> element, referring to this external style sheet, might look as shown below. The values of the rel and type attributes should always be "stylesheet" and "text/css," respectively. The href attribute's value will be the URI of whatever stylesheet is to be used.

Example

XML File (bookextcss.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="bookextcss.xsl" ?>
<book>
    <book_title>Jambing on the Trixles</book_title>
    <author> Randall, Tristan</author>
</book>

CSS File (book.css)

h1
{ font-family: Arial,Univers,sans-serif;
  font-size: 36pt
}

XSLT File (bookextcss.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="book">
    <html>
<head>
            <title>Book Info</title>
        <link rel="stylesheet" type="text/css" href="book.css" />
    </head>
    <body><xsl:apply-templates/></body>
    </html>
</xsl:template>

<xsl:template match="book_title">
    <h1><xsl:value-of select="."/></h1>
</xsl:template>

</xsl:stylesheet>

XSLT Processor Output

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-16">
<title>Book Info</title>
<link rel="stylesheet" type="text/css" href="book.css">
</head>
<body><h1>Jambing on the Trixles</h1> Randall, Tristan</body>
</html>

Formatted Output

See Also

Incorporating <style> Elements into an XSLT File


Using Namespaces with CSS

Namespaces must be declared on the <document> element when using XML with a CSS. Locally scoped namespaces will parse correctly, but CSS does not currently describe a mechanism for resolving namespace prefixes; thus, CSS rules might not apply correctly to elements in the locally scoped namespace. Placing all namespace declarations on the <document> element ensures that they are all "global" and thus, there will be no collision of prefixes. The default namespace cannot be used—all namespaced elements must have an explicit prefix. In addition, CSS selectors can specify a namespaced element only by its prefix, so ensure that the prefix is consistent between the XML document and the style sheet.

Here is an example of a style sheet for elements with the "HTML" prefix.

CSS File (htmlprefix.css)

HTML\:IMG {
  border: 2px solid black;
}
HTML\:A:visited HTML\:IMG {
  border-color: grey;
}
HTML\:A:active HTML\:IMG {
  border-color: red;
}
HTML\:A:link HTML\:IMG {
  border-color: blue;
}

Notice that the ":" namespace character must be escaped by a leading backslash to differentiate it from a pseudoclass.

Using the HTML Namespace with CSS

The HTML namespace is treated specially when browsing XML with CSS. Elements from the HTML namespace are displayed as they would appear in HTML. This allows access to capabilities not yet provided by CSS. Some examples of useful HTML elements to embed are <TABLE>, <A>, <IMG>, <SCRIPT>, and <STYLE>.

For example, you can add a link and logo to the restaurant review sample. First, you must declare the HTML namespace at the top of the document and then use the "HTML" prefix on the embedded HTML elements. HTML embedded this way must be well-formed XML, so the <IMG> element needs a minimized end tag.

<story xmlns:HTML="http://www.w3.org/Profiles/XHTML-transitional">
  ...
  <restaurant>
    <name>Red Apple Inn</name>
    <logo>
      <HTML:A href="javascript:alert('Visit the Red Apple Inn!')">
        <HTML:IMG src="red-apple.gif" height="50" width="200"/>
      </HTML:A>
    </logo>
    ...

In Microsoft® Internet Explorer 5.0, the prefix must remain "HTML" or "html" in order for the elements to be interpreted as HTML elements.

An <HTML:STYLE> block can be used to embed a CSS style sheet within an XML document. This block will augment any style sheets pointed to by style sheet processing instructions. When there is no external style sheet, there still must be a style sheet processing instruction present to indicate that the XML document should be displayed using the CSS style sheet language, even though no "href" attribute is specified.

The following example shows how the review.css style sheet can be embedded into the XML document using the HTML namespace, the <HTML:STYLE> element, and the style sheet processing instruction without an "href" attribute.

<?xml version="1.0"?>
<?xml-stylesheet type="text/css"?>
<story xmlns:HTML="http://www.w3.org/Profiles/XHTML-transitional">
  <HTML:STYLE>
    story
    {
      display: block;
      font-family: Arial, Helvetica, sans-serif;
      font-size: small;
      width: 30em;
    }
    restaurant
    {
      display: block;
      padding: 1.2em;
      font-size: x-small;
      margin-bottom: 1em;
    }
    ...
  </HTML:STYLE>
  <restaurant>
    ...

Try it! The restaurant Review sample includes the following files. The various versions display identically, but reference the style sheet in different ways.

File name | Description
review-embedded-css.xml | This XML file has an embedded CSS section.
review-css.xml | This XML file references a separate CSS file.
review.css | This CSS file is used by an XML file.
review-xsl.xml | This XML file references a separate XSL file.
review.xsl | This XSL file is used by an XML file.

XSLT Developer's Guide Samples Other Resources


XSLT Requirements for Viewing XML in a Browser

XSLT files used to view an XML file in a Web browser have stricter requirements than those used for transforming to a general XML file. For more information about authoring an XSLT style sheet, see Template-Driven Transformations. When authoring a style sheet for use in direct browsing, be aware of the following limitations.

  • The style sheet must target HTML as its output.
    • The style sheet applies to the root of the source document. Style sheets written to process against the document element will generally not display correctly. For information about the difference between the document root and the document element, see How the DOM Defines the Context for XPath Expressions.
    • The XSLT style sheet must come from the same URL scheme (for example, http) and host name (for example, www.microsoft.com) as the XML source. The style sheet download follows the same security policies as those for fetching an external entity. Attempting to read a style sheet from a different domain results in an access violation error unless the security option Access data across domains is selected from the Internet Options dialog box.

Microsoft® Internet Explorer 5.0 uses a style sheet to display an XML document when that document contains a style sheet processing instruction with type "text/xsl".

<?xml-stylesheet type="text/xsl" href="review.xsl" ?>


Accessing XML and XSLT Documents from Script

The HTML that results from browsing XML with an XSLT style sheet is fully scriptable using the Introduction to the Dynamic HTML (DHTML) Object Model. In addition, there are two properties available on the DHTML document object that provide script access to the XML and XSLT documents.

  • The document.XMLDocument property returns the root node of the XML source document.
  • The document.XSLDocument property returns the root node of the XSLT style sheet document.

Modifications to these two documents through the DOM do not automatically cause updates to the resulting HTML tree, but rather offer a hook that you can use to wire up the specific updates you need.

Consider the following example, which shows how the menu is dynamically sorted in the Review Sample (XSLT). First, add the links that trigger sorting to the style sheet.

<P class="tagline">
  <A href="javascript:sort('price')">Sort menu by price</A>
  <A href="javascript:sort('description')">Sort menu by description</A>
</P>

Next, write the "sort" function to apply the sort to the menu data and update the display. The script accesses the DOM for the XSLT style sheet with the XSLDocument property and uses DOM calls to change attributes representing sort keys.

The XMLDocument is used to locate the XML source fragment that will be used in the update. Calling transformNode on the fragment will result in a string of HTML that can be pasted back into the HTML document.

function sort(key) {
  // Find the "xsl:sort select" attributes in the style sheet.
  var s = document.XSLDocument.selectNodes(
  "*/xsl:template[@match='menu']//xsl:apply-templates/xsl:sort/@select");

  // Replace the values with the new sort key.
  for (var i = s.nextNode(); i != null; i = s.nextNode())
  {
    i.value = key;
  }

  // Find the subset of the document we need to update.
  var d = document.XMLDocument.selectSingleNode("story/menu");

  // Apply the style sheet to the subset, and update the display.
  menu.innerHTML = d.transformNode(document.XSLDocument);
}

In this example, the style sheet is modified to generate a different view of the XML. The same mechanisms can be used to change the XML source data and to generate updated views of this data.


Serving Out XML Files from an HTTP Server

XML documents can be delivered through a standard HTTP server by registering the "text/xml" Multipurpose Internet Mail Extension (MIME) type on the server. Installing Microsoft® Internet Explorer 5.0 on the server registers the XML MIME type and associates it with the .xml and .xsl file extensions. This association is used by Microsoft Internet Information Services (IIS) and the Microsoft Personal Web Server (PWS) to determine the MIME type.

When using either of these servers on systems that do not have Internet Explorer 5.0 installed, the XML MIME type can be registered by running the register-xml.regregister-xml.reg file, which inserts the appropriate keys into the registry. The changes will not take effect until the computer has been restarted.

Alternatively, for IIS on systems that do not have Internet Explorer 5.0 installed, the XML MIME type can be registered using the Internet Service Manager console. Select Default Web Site and open the Properties dialog box. Select the HTTP Headers tab, click the File Types tab, select New Type, type .xml for the extension and text/xml for the Content Type, and then click OK. The .xsl extension can be registered in a similar fashion.

The .xml and .xsl extensions can also be registered to the XML MIME type manually from the File Types dialog box under Folder Options. Extensions indicating other types of XML files for purposes of browsing must be manually registered as MIME type "text/xml".

Declaring the XML MIME Type in an Active Server Page

When generating XML dynamically using Active Server Pages (ASP), the content type must be declared in the .ASP file itself. The ContentType property of the Response object indicates that the result is XML. Include this line in Active Server Pages that are delivering XML.

<% Response.ContentType = "text/xml" %>
Important If the XML MIME type is not registered on the server, the MIME type sent to Internet Explorer in the HTTP header will be incorrect—often "text/plain". Although Internet Explorer 5.0 often can detect and process these documents, conflicts can arise between the various detection algorithms. For example, part of Channel Definition Format (CDF) file detection involves looking for <CHANNEL> tags—an XML document delivered with an incorrect MIME type and that uses elements named "CHANNEL" could mistakenly be handed off to the CDF processor instead of displayed as an XML document. Avoid these tricky and hard-to-debug problems by making sure your server correctly sends the XML MIME type.

Internet Explorer 5.0 also recognizes documents of MIME type "application/xml" as XML; see Internet Engineering Task Force Request for Comments 2376, XML Media Types (IETF RFC2376) (external link).

See Also

Deploying XSLT Solutions


Using XSLT from the DOM

The Microsoft® XML Parser (MSXML) makes Extensible Stylesheet Language Transformations (XSLT) services available from the DOM. This integration of XSLT with the DOM makes building XML applications simpler and more powerful. XSLT becomes a general service for locating and manipulating XML data in Web pages, server-side applications, and stand-alone applications.

XSLT functionality is accessed through two pairs of DOM methods:

  • selectNodes and selectSingleNode perform XPath queries over a DOM document.
  • transformNode and transformNodeToObject perform complete XSLT transformations on a DOM node.

This section shows how to use XSLT services in your application. It covers the following:

  • Using XSLT with DOM
  • Using XSLT within ASP
  • Getting Transformation Results as a DOM Document
  • Performing Error Handling with XSLT
  • Transforming XML Data Islands in an HTML Page


Using XSLT with DOM

There are a number of ways to apply an Extensible Stylesheet Language Transformations (XSLT) file to a source document using the DOM.

A script must do the following:

  • Load the source document and XSLT file.
  • Transform the source document with the XSLT file, using either the transformNode or the transformNodeToObject method.

To trigger the correct function, associate it with an event on the page—typically the onload event for the document as a whole or, for buttons, images and hyperlinks, the onclick or other mouse events.

Code in this topic uses JScript as the scripting language.

  • Example of XSLT and DOM
  • Implementing Error Handling with XSLT and DOM
  • Increasing Performance by Using the XSLTemplate Object


Example of XSLT and DOM

This example shows how to use the DOM from within an HTML file to transform an XML file.

The qsalesregion.html file is the main file for this example.

First, when the <body> element of the HTML document is loaded, the transformIt() function is immediately invoked. This function does not insert the transformed data from region.xml; it simply makes it available for insertion later in the HTML document.

Second, within the <body> element is a single <div> element with a unique id attribute, whose value is "transformedXML." This value will be used by the transformIt() function as a trigger for the point at which to insert the transformed data from region.xml.

The transformIt() function itself performs several steps:

  1. Binds the result tree to a portion of the document itself (here, the portion(s) tagged with an id attribute whose value is "transformedXML").
  2. Loads region.xml and region.xsl into their respective DOMDocument objects.
  3. Assigns to a string variable the result of the transformation (transformNode) of region.xml by region.xsl.
  4. Assigns to the result tree (established in step 1) the value of the string returned by the transformNode method (in step 3).

Example

HTML File (qsalesregion.html)

<html>
<head>
<title>Quarterly Sales, by Region</title>
<script language='JScript'>
<!--
function transformIt() {
    // Associate the result tree object with any element(s) whose
    // id attribute is "transformedXML."
    var objResTree = document.all['transformedXML'];
    // Declare two new MSXML DOMDocument objects.
    var objSrcTree = new ActiveXObject('MSXML2.DOMDocument');
    var objXSLT = new ActiveXObject('MSXML2.DOMDocument');
    // Load the two DOMDocuments with the XML document and the
    // XSLT style sheet.
    objSrcTree.load('region.xml');
    objXSLT.load('region.xsl');
    // Use the transformNode method to apply the XSLT to the XML.
    strResult = objSrcTree.transformNode(objXSLT);
    // Assign the resulting string to the result tree object's
    // innerHTML property.
    objResTree.innerHTML = strResult;
    return true;
    }
-->
</script>
<body onload='transformIt()'>
<div id='transformedXML'></div>
</body>
</html>

XML File (region.xml)

Note that this document contains no <?xml-stylesheet?> processing instruction.

<?xml version="1.0" ?>
<region year="1999">
<name>Western Region</name>
<quarter number="1" books_sold="24000"/>
<quarter number="2" books_sold="38600"/>
</region>

XSLT File (region.xsl)

<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <!-- Template rule for region element(s) -->
   <xsl:template match="region">
      <h1><xsl:value-of select="@year"/> Results:</h1>
      <xsl:apply-templates/>
   </xsl:template>

   <!-- Template rule for name element(s) -->
   <xsl:template match="name">
          <!-- Instantiate a level-2 heading -->
      <h2><xsl:value-of select="."/></h2>
      <!-- Instantiate a table with heading cells... -->
      <table>
         <tr>
            <th align="left">Quarter</th>
            <th align="right">Qty</th>
         </tr>
         <!-- ...and for each <quarter> sibling of the <name> element,
              instantiate a table row and two cells. Data in the cells
              will be the values of the <quarter> element's number and
         books_sold attributes. -->
         <xsl:for-each select="../quarter">
            <tr>
               <td align="left"><xsl:value-of select="@number"/></td>
               <td align="right"><xsl:value-of select="@books_sold"/></td>
            </tr>
         </xsl:for-each>
      </table>
   </xsl:template>

</xsl:stylesheet>

Formatted Output

HTML Output File with Result Tree from DOM

Internet Explorer would actually display the document with region.xml's contents, after the transformation, as if its HTML code were as follows (generated HTML is shown here in bold):

<html>
<head>
<title>Quarterly Sales, by Region</title>
<body>
<div>
<h2>Western Region</h2>
<table>
<tr>
    <th align="left">Quarter</th>
    <th align="right">Qty</th>
</tr>
<tr>
    <td align="left">1</td>
    <td align="right">24000</td>
</tr>
<tr>
    <td align="left">2</td>
    <td align="right">38600</td>
</tr>
</table>
</div>
</body>
</html>

See Also

Implementing Error Handling with XSLT and DOM


Implementing Error Handling with XSLT and DOM

There are no special error-handling methods or properties for determining that the transformation works as intended. When processing XSLT or XML, the most important error handling facilities are:

  • The validateOnParse property of a DOMDocument object. Set to False prior to loading the object, the parser simply checks for well-formedness; to True, for validity against a DTD or schema.
  • The parseError object's errorCode property, which is the result of loading the XSLT style sheet (or other document). If this property's value is 0, the parse succeeded; if any other value, it failed. In the latter case, a number of other properties are available to provide information about the nature of the error.

Error Handling with the Region.xsl Example

To check region.xsl for validity, add the following JScript fragments where indicated below. For more information about the files for this example, see Example of XSLT and DOM.

Insert the following line immediately after the declaration of the objXSLT object variable:

objXSLT.validateOnParse = true;

Insert the following lines immediately after the objXSLT.load('region.xsl') statement:

if objXSLT.parseError.errorCode <> 0 {
var strErrMsg as new String;
strErrMsg = "Problem Parsing Style Sheet:<br />"
    + "  Error #: " + objXSLT.parseError.errorCode + "<br />"
    + "  Description: " + objXSLT.parseError.reason" + "<br />"
    + "  In file: " + objXSLT.parseError.url + "<br />"
    + "  Line #: " + objXSLT.parseError.line + "<br />"
    + "  Character # in line: " + objXSLT.parseError.linepos + "<br />"
    + "  Character # in file: " + objXSLT.parseError.filepos + "<br />"
    + "  Source line: " + objXSLT.parseError.srcText;
objResTree.innerHTML = strErrMsg;
return false;
}

The resulting file is shown in XSLT HTML DOM File with Error Checking.

Similar logic for validating the XML document (region.xml) could be provided at analogous locations in the script.

See Also

Performing Error Handling with XSLT


XSLT HTML DOM File with Error Checking

Lines added for error handling are shown in bold.

HTML File (qsalesregionwerrchk.html)

<html>
<head>
<title>Quarterly Sales, by Region</title>
<script language='JScript'>
<!--
function transformIt() {
    // Associate the result tree object with any element(s) whose
    // id attribute is "transformedXML."
    var objResTree = document.all['transformedXML'];
    // Declare two new MSXML DOMDocument objects.
    var objSrcTree = new ActiveXObject('MSXML2.DOMDocument');
    var objXSLT = new ActiveXObject('MSXML2.DOMDocument');
    objXSLT.validateOnParse = true;
    // Load the two DOMDocuments with the XML document and the
    // XSLT style sheet.
    objSrcTree.load('region.xml');
    objXSLT.load('region.xsl');
if objXSLT.parseError.errorCode <> 0 {
var strErrMsg as new String;
strErrMsg = "Problem Parsing Style Sheet:<br />"
    + "  Error #: " + objXSLT.parseError.errorCode + "<br />"
    + "  Description: " + objXSLT.parseError.reason" + "<br />"
    + "  In file: " + objXSLT.parseError.url + "<br />"
    + "  Line #: " + objXSLT.parseError.line + "<br />"
    + "  Character # in line: " + objXSLT.parseError.linepos + "<br />"
    + "  Character # in file: " + objXSLT.parseError.filepos + "<br />"
    + "  Source line: " + objXSLT.parseError.srcText;
objResTree.innerHTML = strErrMsg;
return false;
}
    // Use the transformNode method to apply the XSLT to the XML.
    strResult = objSrcTree.transformNode(objXSLT);
    // Assign the resulting string to the result tree object's
    // innerHTML property.
    objResTree.innerHTML = strResult;
    return true;
    }
-->
</script>
<body onload='transformIt()'>
<div id='transformedXML'></div>
</body>
</html>


Increasing Performance by Using the XSLTemplate Object

This section is more advanced than browsing XML documents. Using the transformNode and transformNodeToObject methods is simple and straightforward for the majority of simple applications. However, these methods result in performance penalties when a particular XSLT style sheet needs to be processed iteratively, many times in the course of a given script. Each succeeding invocation of transformNode or transformNodeToObject re-reads, -parses, and -interprets all template rules in the stylesheet; the style sheet's parse tree is not retained in memory.

To avoid this performance hit, MSXML makes available an XSLTemplate object. This object holds a compiled form of the style sheet, essentially an in-memory representation of the style sheet's parse tree and template rules which can be referred to in succeeding passes, obviating the need for re-parsing.

The steps necessary to use the XSLTemplate object are:

  1. Load the XSL style sheet in question.
  2. Create an XSLTemplate object, and set its stylesheet property to the documentElement property of the style sheet object itself.
  3. Create an XSLProcessor object to hold the transformation.
  4. For each XML source node to be transformed, set the values of any parameters necessary for the transformation to function, and invoke the transform method to apply the transformation to the XML source.

This approach can be implemented in four files: .xml, .xsl, .asa, and .asp.

Loading the XSL Style Sheet

Prior to invoking the load method, you should first declare the style sheet object not as a simple DOMDocument, but as a FreeThreadedDOMDocument.

To cache the template, the template must be freethreaded. This enables you to load and cache the template within application scope or load it into an object manager.

Be sure to set the async property of this object to false as well, to ensure that the entire style sheet is loaded before beginning the transform. For example, you could have the following JScript coding within a global.asa file:

objXSLT = new ActiveXObject("MSXML2.FreeThreadedDomDocument");
objXSLT.async = false;
objXSLT.load("region.xsl");

Creating the XSLTemplate Object and XSLProcessor in Cache

In a cached file such as global.asa, create the XSLTemplate object and XSLProcessor object, as follows.

Create the XSLTemplate object:

objCompiled = new ActiveXObject("MSXML2.XSLTemplate");

Set its stylesheet property as well:

objCompiled.stylesheet = objXSLT.documentElement;

XSLTemplate by itself does not perform the transform; that function is handled by the XSLProcessor object. So the next step is to create the XSLProcessor which will be invoked each time you need to perform the transform:

Var objXSLProc = objCompiled.createProcessor();

Now you can invoke this cached template efficiently, from a separate file.

Invoking the XSLProcessor for Each Transform

You can invoke the cached template from a .asp file as follows.

At the least, you need to perform two steps to invoke the XSLProcessor's transformation:

  1. Identify to the XSLProcessor object the source XML node (which may be an entire document) to be transformed.
  2. Invoke the transform method on the XSLProcessor object.

More often, the XSLProcessor's transformation will be driven by one or more external parameters, whose names and values need to be passed into it using the addParameter method before invoking the transform method. Thus (assuming three external parameters), the JScript code to apply the transformation each time it is needed would be:

objXSLProc.input = objXML;
// Note: The third argument to the addParameter method is the namespace
// URI, if any, for the corresponding parameter's name. If none, set it
// to an empty string.
objXSLProc.addParameter("param1", "value1", "");
objXSLProc.addParameter("param2", "value2", "");
objXSLProc.addParameter("foo:param3", "value3", "http://www.foo.org");
objXSLProc.transform();

Finally, add the output property of the XSLProcessor object to the result tree:

objResTree.innerHTML = objXSLProc.output;

Another approach is to use addObject().


Using XSLT within ASP

You can perform Extensible Stylesheet Language Transformations (XSLT) at the server to filter or customize XML or to change its schema. You can also deploy content in XML and transform it to HTML on demand for clients.

The code for performing XSLT within an Active Server Pages (ASP) file is similar to that used on the client. For more information, see Transforming XML Data Islands in an HTML Page.

You load the XML source document and XSLT file, then call transformNode to link to the XSLT processor.

<%@ LANGUAGE = JScript %>
<%
  // Set the source and style sheet locations here
  var sourceFile = Server.MapPath("simple.xml");
  var styleFile = Server.MapPath("simple.xsl");

  // Load the XML
  var source = Server.CreateObject("MSXML2.DOMDocument");
  source.async = false;
  source.load(sourceFile);
  // Load the XSLT
  var style = Server.CreateObject("MSXML2.DOMDocument");
  style.async = false;
  style.load(styleFile);
  Response.Write(source.transformNode(style));
%>

The previous code uses a version-independent progID, in CreateObject("MSXML2.DOMDocument"). For more information, see Installing MSXML 4.0 for XSLT Support.

The Server.MapPath method resolves a relative URL to a full path. The Server.CreateObject instantiates a new XML DOM Document object. The results of the transformation are sent to the client using the Response.Write method.

The transformNodeToObject method offers the ability to write a transformation directly to the IStream interface of the response object. To use this feature, the last line in the preceding example would instead become as follows.

source.transformNodeToObject(style, Response);

In most situations, this method performs better on the server, especially for long documents, which require a significant memory allocation to hold the complete transformation results.

For an example of a transformNodeToObject call, see simple.asp in XSLT Sample: Breakfast Menu.


Getting Transformation Results as a DOM Document

The transformNodeToObject method provides a way to generate a new Document Object Model (DOM) document instead of XML text. In this example, data islands are used to load the XML source and the style sheet, and an empty data island is created that will hold the results of the transformation.

<HTML>
  <SCRIPT FOR="window" EVENT="onload">
    data.transformNodeToObject(ss.XMLDocument, resultTree.XMLDocument);
  </SCRIPT>

  <XML id="data" src="portfolio.xml"></XML>
  <XML id="ss" src="portfolio.xsl"></XML>
  <XML id="resultTree"></XML>
</HTML>

Like the transformNode method, the transformNodeToObject method is applied to a node in the source tree, and accepts a style sheet in the form of a DOM tree. A second parameter contains another DOM Document node that will hold the results of the transformation.

Properties set on the output XML DOM Document, such as validateOnParse and async, will be honored during the transformation. Any previous children will be deleted during the transformation.

Try it! The preceding code is a simplification of the Transformation Viewer sample found at XSLT Developer's Guide Samples.

Other Resources Other Resources

XSLT Developer's Guide Samples


Performing Error Handling with XSLT

An XSLT file can generate two types of errors: parse errors and run-time errors. There are ways to check for these errors and report them.

Here is a simple HTML page that uses XML data islands to load an XML file and an XSLT style sheet and display the results.

<HTML>
  <XML id="source" src="simple.xml"></XML>
  <XML id="style" src="simple.xsl"></XML>
  <SCRIPT event="onload" for="window">
    showResult.innerHTML = source.transformNode(style.XMLDocument);
  </SCRIPT>
  <BODY>
    <DIV id="showResult"></DIV>
  </BODY>
</HTML>

The call to transformNode invokes the XSLT processor, and the resulting HTML is inserted into the page.

If nothing appears, first check the parseError object to see if there was a parsing error in the XML file or style sheet. Parsing errors on data islands do not generate error messages in the browser. If an error occurred, you can retrieve the cause or put an error message into the page. In the following example, parsing errors are checked for; if they occur, a function is called to format the error information in a way appropriate for inserting into the HTML document.

<HTML>
  <HEAD>
    <TITLE>Simple Error Message Demo</TITLE>
  </HEAD>

  <XML id="source" src="review.xml"></XML>
  <XML id="style" src="review.xsl"></XML>

  <SCRIPT src="reportErrors.js"></SCRIPT>
  <SCRIPT event="onload" for="window">
    if (source.parseError.errorCode != 0)
      result = reportParseError(source.parseError);
    else
    {
      if (style.parseError.errorCode != 0)
        result = reportParseError(style.parseError);
      else
      {
        try {
          result = source.transformNode(style.XMLDocument);
        }
        catch (exception) {
          result = reportRuntimeError(exception);
        }
      }
    }
    // Insert the results into the page.
    showResult.innerHTML = result;
  </SCRIPT>
  <BODY>
    <DIV id="showResult"></DIV>
  </BODY>
</HTML>

In addition to parsing errors, the preceding example also detects XSLT run-time errors, those occurring inside calls to transformNode. Run-time errors will normally be reported to the user through a Microsoft® Internet Explorer 5.0 or later error dialog box. However, it is often useful to suppress this dialog box. The try and catch functions in Microsoft JScript® (compatible with ECMA 262 language specification) allow the error to be suppressed and handled consistently with parsing errors.

The actual formatting of the error information in the previous example is provided by two functions: reportParseError and reportRuntimeError, which reside in a separate script file, reportErrors.js. The main HTML page references this script file.

JScript File (reportErrors.js)

// Parse error formatting function
function reportParseError(error)
{
  var s = "";
  for (var i=1; i<error.linepos; i++) {
    s += " ";
  }
  r = "<font face=Verdana size=2><font size=4>XML Error loading '" +
      error.url + "'</font>" +
      "<P><B>" + error.reason +
      "</B></P></font>";
  if (error.line > 0)
    r += "<font size=3><XMP>" +
    "at line " + error.line + ", character " + error.linepos +
    "\n" + error.srcText +
    "\n" + s + "^" +
    "</XMP></font>";
  return r;
}
// Runtime error formatting function.
function reportRuntimeError(exception)
{
  return "<font face=Verdana size=2><font size=4>XSL Runtime Error</font>" +
      "<P><B>" + exception.description + "</B></P></font>";
}

These two functions return HTML fragments that can be inserted into the HTML page in place of the correct transformation result, alerting you to a problem.

Try it! The following samples, found in the Review demo, demonstrate the preceding code in various error situations.

  • Error Message Demo (XML Source Parsing Error)
  • Error Message Demo (XSLT Style Sheet Parsing Error)
  • Error Message Demo (XSLT Run-time Error)
  • Error Message Demo (XSLT Script Error)
  • Error Message Demo (No Errors)

For more information about the Review demo, see XSLT Developer's Guide Samples.

For more information and the XSL version of these samples, see XSL Developer's Guide Samples.

Reporting an error using this mechanism is also useful in an Active Server Page (ASP). Here is the equivalent code for processing an XML file on the server.

<%@ LANGUAGE = JScript %>
<%
  // Parse error formatting function.
  function reportParseError(error)
  {
    var s = "";
    for (var i=1; i<error.linepos; i++) {
      s += " ";
    }
    r = "<font face=Verdana size=2><font size=4>XML Error loading '" +
        error.url + "'</font>" +
        "<P><B>" + error.reason +
        "</B></P></font>";
    if (error.line > 0)
      r += "<font size=3><XMP>" +
      "at line " + error.line + ", character " + error.linepos +
      "\n" + error.srcText +
      "\n" + s + "^" +
      "</XMP></font>";
    return r;
  }
  // Run-time error formatting function.
  function reportRuntimeError(exception)
  {
    return "<font face=Verdana size=2><font size=4>XSL Runtime Error</font>" +
        "<P><B>" + exception.description + "</B></P></font>";
  }
  // Set the source and style sheet locations here.
  var sourceFile = Server.MapPath("review.xml");
  var styleFile = Server.MapPath("review-simple.xsl");

  // Load the XML.
  var source = Server.CreateObject("MSXML2.DOMDocument");
  source.async = false;
  source.load(sourceFile);
  // Load the XSL.
  var style = Server.CreateObject("MSXML2.DOMDocument");
  style.async = false;
  style.load(styleFile);
  if (source.parseError.errorCode != 0)
    result = reportParseError(source.parseError);
  else
  {
    if (style.parseError.errorCode != 0)
      result = reportParseError(style.parseError);
    else
    {
      try {
        result = source.transformNode(style);
      }
      catch (exception) {
        result = reportRuntimeError(exception);
      }
    }
  }
  Response.Write(result);
%>

The code here is essentially the same as that for the client side, with the same error formatting functions and processing. The Server.CreateObject and Response.Write methods are used in place of the client-side functions provided by data islands and the innerHTML method.

Try it! The following samples, found in the Review demo at XSLT Developer's Guide Samples, demonstrate the above code in various error situations.

  • ASP Error Message Demo (XML Source Parsing Error)
  • ASP Error Message Demo (XSLT Style Sheet Parsing Error)
  • ASP Error Message Demo (XSLT Run-time Error)
  • ASP Error Message Demo (XSLT Script Error)
  • ASP Error Message Demo (No Errors)

See the XSL version of these samples at XSL Developer's Guide Samples.

See Also

Implementing Error Handling with XSLT and DOM

Other Resources Other Resources

XSLT Developer's Guide Samples


Transforming XML Data Islands in an HTML Page

This approach can be used if the transform occurs via Microsoft® Internet Explorer. For more information, see Deploying XSLT in Internet Explorer.

Data islands provide a convenient way to access XML data from an HTML page. Because XSL Transformations (XSLT) is an XML grammar itself, data islands also provide a convenient way to load style sheets. The simple-islands.htm example uses two data islands to load both the source XML data and the XSLT style sheet. The transformNode method is used on these two data islands to generate HTML that can then be inserted into the page.

When this page, including the data islands, is completely loaded, the onload event fires and the transformNode method is executed upon the XML source data. transformNode takes a single parameter, which is a Document Object Model (DOM) node representing a style sheet. The result of this call is XML text. Because the simple.xsl style sheet used in this example generates well-formed HTML, you can feed this into the xslTarget <DIV> element for display using the innerHTML property.

The XMLDocument property is used on the "style" data island. Without this property, the ID of a data island (for example, "style") is treated as identifying an HTML element, in this case the <XML> element. XMLDocument can be used to explicitly obtain the XML DOM Document node from the <XML> element. Writing style.XMLDocument makes it clear that you are operating on the contents of the data island and not the <XML> element representing the data island.

You do not need to write source.XMLDocument.transformNode(style.XMLDocument). If a method from the XML DOM is applied to the data island element, the script engine interface reasons that you want this method applied to the XML DOM Document node instead, and thus the XMLDocument property can be omitted if another DOM property or method is being applied. In the case of the "source" data island, you are calling a DOM method (transformNode); therefore, the XMLDocument property is not required.

You can also write source.XMLDocument.transformNode(style.documentElement) and apply the style sheet to the document element instead of the root, but the style sheet must reflect this—for example, the document element must be handled by a rule other than the root template xsl:template match="/", which will not be invoked unless the style sheet is executed against the document root. It is recommended that you process your style sheets off the document root so they will also work for direct browsing of XML. For more information about the differences between the document root and the document element, see How the DOM Defines the Context for XPath Expressions.

Example

For an example of an HTML page with XML Data Islands, see simple-islands.htm in XSLT Sample: Breakfast Menu.

See Also

XML Data Islands | Performing Error Handling with XSLT | Getting Transformation Results as a DOM Document


XSLT Sample: Breakfast Menu

This Breakfast Menu sample demonstrates XML data islands and includes the following files:

  • simple-islands.htm
  • simple.xml
  • simple.xsl
  • simple.asp

HTML File (simple-islands.htm)

<HTML>
  <HEAD>
    <TITLE>Simple demo of Microsoft XSL Processor</TITLE>
  </HEAD>

  <XML id="source" src="simple.xml"></XML>
  <XML id="style" src="simple.xsl"></XML>

  <SCRIPT FOR="window" EVENT="onload">
    xslTarget.innerHTML = source.transformNode(style.XMLDocument);
  </SCRIPT>

<BODY>
    <P STYLE="font-size:10pt; font-family:Verdana; color:gray">
      <B>This demo shows the use of data islands for loading XML source and
      XSL style sheets and inserting the transformed result into the Web page.</B>
    </P>
    <DIV id="xslTarget"></DIV>
  </BODY>
</HTML>

XML File (simple.xml)

<?xml version='1.0'?>
<?xml:stylesheet type="text/xsl" href="simple.xsl" ?>
<breakfast-menu>
  <food>
    <name>Belgian Waffles</name>
    <price>$5.95</price>
    <description>two of our famous Belgian Waffles with plenty of real maple syrup</description>
    <calories>650</calories>
  </food>
  <food>
    <name>Strawberry Belgian Waffles</name>
    <price>$7.95</price>
    <description>light Belgian waffles coverred with strawberrys and whipped cream</description>
    <calories>900</calories>
  </food>
  <food>
    <name>Berry-Berry Belgian Waffles</name>
    <price>$8.95</price>
    <description>light Belgian waffles coverred with an assortment of fresh berries and whipped cream</description>
    <calories>900</calories>
  </food>
  <food>
    <name>French Toast</name>
    <price>$4.50</price>
    <description>thick slices made from our homemade sourdough bread</description>
    <calories>600</calories>
  </food>
  <food>
    <name>Homestyle Breakfast</name>
    <price>$6.95</price>
    <description>two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>
    <calories>950</calories>
  </food>
</breakfast-menu>

XSLT File (simple.xsl)

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
  <xsl:template match="/">
    <HTML>
      <BODY STYLE="font-family:Arial, helvetica, sans-serif; font-size:12pt;
            background-color:#EEEEEE">
        <xsl:for-each select="breakfast-menu/food">
          <DIV STYLE="background-color:teal; color:white; padding:4px">
            <SPAN STYLE="font-weight:bold; color:white"><xsl:value-of select="name"/></SPAN>
            - <xsl:value-of select="price"/>
          </DIV>
          <DIV STYLE="margin-left:20px; margin-bottom:1em; font-size:10pt">
            <xsl:value-of select="description"/>
            <SPAN STYLE="font-style:italic">
              (<xsl:value-of select="calories"/> calories per serving)
            </SPAN>
          </DIV>
        </xsl:for-each>
      </BODY>
    </HTML>
  </xsl:template>
</xsl:stylesheet>

ASP File (simple.asp)

<HTML>
<HEAD>
<!--TOOLBAR_START-->
<!--TOOLBAR_EXEMPT-->
<!--TOOLBAR_END-->
</HEAD>
<BODY STYLE="font-family:Arial, helvetica, sans-serif; font-size:12pt;
        background-color:#EEEEEE">
<DIV STYLE="background-color:teal; color:white; padding:4px">
<SPAN STYLE="font-weight:bold; color:white">Belgian Waffles</SPAN>
        - $5.95
</DIV>
<DIV STYLE="margin-left:20px; margin-bottom:1em; font-size:10pt">
two of our famous Belgian Waffles with plenty of real maple syrup
<SPAN STYLE="font-style:italic">
          (650 calories per serving)
        </SPAN>
</DIV>
<DIV STYLE="background-color:teal; color:white; padding:4px">
<SPAN STYLE="font-weight:bold; color:white">Strawberry Belgian Waffles</SPAN>
        - $7.95
</DIV>
<DIV STYLE="margin-left:20px; margin-bottom:1em; font-size:10pt">
light Belgian waffles coverred with strawberrys and whipped cream
<SPAN STYLE="font-style:italic">
          (900 calories per serving)
        </SPAN>
</DIV>
<DIV STYLE="background-color:teal; color:white; padding:4px">
<SPAN STYLE="font-weight:bold; color:white">Berry-Berry Belgian Waffles</SPAN>
        - $8.95
</DIV>
<DIV STYLE="margin-left:20px; margin-bottom:1em; font-size:10pt">
light Belgian waffles coverred with an assortment of fresh berries and whipped cream
<SPAN STYLE="font-style:italic">
          (900 calories per serving)
        </SPAN>
</DIV>
<DIV STYLE="background-color:teal; color:white; padding:4px">
<SPAN STYLE="font-weight:bold; color:white">French Toast</SPAN>
        - $4.50
</DIV>
<DIV STYLE="margin-left:20px; margin-bottom:1em; font-size:10pt">
thick slices made from our homemade sourdough bread
<SPAN STYLE="font-style:italic">
          (600 calories per serving)
        </SPAN>
</DIV>
<DIV STYLE="background-color:teal; color:white; padding:4px">
<SPAN STYLE="font-weight:bold; color:white">Homestyle Breakfast</SPAN>
        - $6.95
</DIV>
<DIV STYLE="margin-left:20px; margin-bottom:1em; font-size:10pt">
two eggs, bacon or sausage, toast, and our ever-popular hash browns
<SPAN STYLE="font-style:italic">
          (950 calories per serving)
        </SPAN>
</DIV>
</BODY>
</HTML>


Using XPath Expressions to Select Nodes

XML Path Language (XPath) is a language used to create expressions that can address parts of an XML document; manipulate strings, numbers, and Booleans; and select a set of nodes in the document. XPath is used by both XSL Transformations (XSLT) and XPointer, and models an XML document as a tree of nodes of different types, including element, attribute, and text. XPath expressions can identify these nodes in the XML document based on their type, name, and values, as well as the relationship of a node to other nodes in the document. An XPath expression yields one of the following basic objects:

  • node set
  • Boolean
  • number
  • string

For example, the query "find 'author' elements that have a 'period' attribute with the value 'classical', and that are contained in the 'authors' element at the document root" can be expressed as in XPath expression as "/authors/author[@period='classical']".

These expressions are a core part of XSLT transformations, which associate the expression results with templates to create a new XML document. Expressions using the XPath syntax can also be performed directly against the XML Document Object Model (DOM).

An important kind of XPath expression is a location path, which is an expression that selects a set of nodes relative to the context node. The result of evaluating a location path is a node-set containing the selected nodes.

The Microsoft® XML Parser (MSXML) implements XPath as described in the XML Path Language (XPath) Version 1.0 Worldwide Web Consortium (W3C) recommendation dated November 16, 1999.

This section covers the following:

  • Introduction to XPath Syntax
  • Introduction to the XPath Tree Model
  • Basic Syntax of XPath Expressions
  • Differences between XPath Expressions and XSLT Patterns
  • Context and Navigation in XPath
  • Working with Lists of Items Using XPath
  • Using XPath Axes to Navigate through XML Data
  • Filtering XML Data Using XPath Predicates
  • Using Functions in XPath Expressions
  • Constructing Complex XPath Searches
  • Useful Patterns for XPath Expressions

See Also

XPath Syntax | Template-Driven Transformations | Defining Match Patterns in <xsl:template>

Other Resources Other Resources

XML Path Language (XPath) Version 1.0


Introduction to XPath Syntax

XPath is the name of a standard endorsed by the World Wide Web Consortium (W3C). Its purpose is to enable locating any one or several nodes within an XML document, often by using multiple alternate routes. An understanding of XPath is critical to successfully using a number of XML-related technologies, including XLink and XPointer as well as XSL Transformations (XSLT). For more information about XPath at W3C, see XML Path Language (XPath) Version 1.0.

XML documents represent a hierarchy or tree of nodes, similar to the hierarchy of directories and files found in a file system. This accounts for the similarity of syntax between URLs and XPath. Some analogous features are compared in the following table.

File System (URLs) | XPath
Hierarchy comprised of directories and files in a file system. | Hierarchy comprised of elements and other nodes in an XML document.
Files at each level have unique names. URLs always identify a single file. | Element names at each level might not be unique. XPath patterns identify a set of all the matching elements.
Evaluated relative to a particular directory, called the "current directory." | Evaluated relative to a particular node called the "context" for the query.

The authors.xml sample file represents a plain hierarchy, which is used to demonstrate some of the basic query facilities of XPath.

XML File (authors.xml)

<?xml version='1.0'?>
<authors>
  <author>
    <name>Victor Hugo</name>
    <nationality>French</nationality>
  </author>
  <author period="classical">
    <name>Sophocles</name>
    <nationality>Greek</nationality>
  </author>
  <author>
    <name>Leo Tolstoy</name>
    <nationality>Russian</nationality>
  </author>
  <author>
    <name>Alexander Pushkin</name>
    <nationality>Russian</nationality>
  </author>
  <author period="classical">
    <name>Plato</name>
    <nationality>Greek</nationality>
  </author>
</authors>

XPath can use any node in the XML document as the context for a query. In an XSLT file, the context for a query is the source node being currently processed by an <xsl:template> or <xsl:for-each> element. When using XPath directly from the DOM, you define the context by performing the query from a particular node. For more information about how a context is defined, see How the DOM Defines the Context for XPath Expressions and How XSLT Defines the Context for XPath Expressions. The examples in this topic use the root of the XML document as the context.

A basic XPath pattern describes a path through the XML hierarchy with a slash-separated list of child element names. Starting from the document root, the following pattern traverses down through the hierarchy of the preceding sample XML document to the <name> elements.

authors/author/name

The XPath pattern identifies all elements that match the path. Because XSLT has the potential for identifying a set of nodes in a tree, it can be used as a simple query mechanism.

In addition to describing a path down a known hierarchy, XPath can include wildcards for describing unknown elements. An element of any name is represented by "*".

authors/*/name

The preceding query also identifies all the name elements, but does not require them to be children of an <author> element. Here is another example that finds both <name> and <nationality> elements.

authors/author/*

Branches on the path can be specified by using square brackets. The following query describes a branch on the <author> element, indicating that only the <author> elements with nationality children should be considered.

authors/author[nationality]/name

This becomes even more useful for the sample data when comparisons are added. The following query returns the names of Russian authors.

Note comparisons can be used only within brackets.
authors/author[nationality='Russian']/name

Attributes are indicated in a query by preceding the name of the attribute with "@". The attribute can be tested as a branch off the main path, or the query can identify attribute nodes. The following examples return authors from the classical period, and just the two period attributes, respectively.

authors/author[@period="classical"]
authors/author/@period

The above XPath expressions are presented in an easy, interactive sample, Sample Files for Introduction to XPath Syntax. Run this sample to see which XML nodes are selected by each XPath expression.

For a complete list of XPath features supported by MSXML, see XPath Syntax.

Other Resources Other Resources

XML Path Language (XPath) Version 1.0


Sample Files for Introduction to XPath Syntax

This interactive sample, Simple XPath Query, highlights the XML nodes that are selected by the XPath expression that you type or click. This sample uses these files:

  • authors.xml — short XML sample data file showing book author information. This listing is also shown in Introduction to XPath Syntax.
  • hilite-xml.xsl — style sheet used by author-patterns.htm to highlight the XPath expression you specify.
  • author-patterns.htm — enables you to type an XPath expression and see the result automatically highlighted in the displayed copy of the XML source document.

To run this sample, copy and save the three files to your drive, and then view author-patterns.htm in Internet Explorer.

XML File (authors.xml)

<?xml version='1.0'?>
<authors>
  <author>
    <name>Victor Hugo</name>
    <nationality>French</nationality>
  </author>
  <author period="classical">
    <name>Sophocles</name>
    <nationality>Greek</nationality>
  </author>
  <author>
    <name>Leo Tolstoy</name>
    <nationality>Russian</nationality>
  </author>
  <author>
    <name>Alexander Pushkin</name>
    <nationality>Russian</nationality>
  </author>
  <author period="classical">
    <name>Plato</name>
    <nationality>Greek</nationality>
  </author>
</authors>

XSLT File (hilite-xml.xsl)

This style sheet is used by author-patterns.htm to highlight the XPath expression you specify.

<?xml version="1.0"?>

<!-- Generic stylesheet for viewing XML -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
  <xsl:template match="/">
    <DIV STYLE="font-family:Courier; font-size:10pt; margin-bottom:2em">
      <xsl:apply-templates />
    </DIV>
  </xsl:template>

  <xsl:template match="*">
    <DIV STYLE="margin-left:1em; color:gray">
      <xsl:attribute name="id"><xsl:eval>makeId(this)</xsl:eval></xsl:attribute>
      &lt;<xsl:node-name/><xsl:apply-templates select="@*"/>/&gt;
    </DIV>
  </xsl:template>

  <xsl:template match="*[node()]">
    <DIV STYLE="margin-left:1em">
      <SPAN STYLE="color:gray">
        <xsl:attribute name="id"><xsl:eval>makeId(this)</xsl:eval></xsl:attribute>
        &lt;<xsl:node-name/><xsl:apply-templates select="@*"/>&gt;</SPAN><xsl:apply-templates select="node()"/><SPAN STYLE="color:gray">&lt;/<xsl:node-name/>&gt;</SPAN>
    </DIV>
  </xsl:template>

  <xsl:template match="@*" xml:space="preserve">
    <SPAN STYLE="color:navy"><xsl:attribute name="id"><xsl:eval>makeId(this)</xsl:eval></xsl:attribute>
    <xsl:node-name/>="<SPAN STYLE="color:black"><xsl:value-of /></SPAN>"</SPAN>
  </xsl:template>

  <xsl:template match="pi()">
    <DIV STYLE="margin-left:1em; color:maroon"><xsl:attribute name="id"><xsl:eval>makeId(this)</xsl:eval></xsl:attribute>&lt;?<xsl:node-name/><xsl:apply-templates select="@*"/>?&gt;</DIV>
  </xsl:template>

  <xsl:template match="cdata()"><pre><xsl:attribute name="id"><xsl:eval>makeId(this)</xsl:eval></xsl:attribute>&lt;![CDATA[<xsl:value-of />]]&gt;</pre></xsl:template>

  <xsl:template match="textNode()"><SPAN><xsl:attribute name="id"><xsl:eval>makeId(this)</xsl:eval></xsl:attribute><xsl:value-of /></SPAN></xsl:template>

  <xsl:script>
      function makeId(e)
      {
        if (e)
          return makeId(e.selectSingleNode("..")) +
            absoluteChildNumber(e) + (e.nodeType == 2 ? "@" : "_");
        else
          return "";
      }
  </xsl:script>
</xsl:stylesheet>

HTML File (author-patterns.htm)

<HTML>
<HEAD>
  <TITLE>Simple XSL Pattern Demo</TITLE>
  <STYLE>
    BODY {font-family:Arial}
    .heading {font-family:"Arial Black"}
    .sample {cursor:hand; font:9pt Courier; text-decoration:underline; text-indent:-1em; margin-left:1em}
    .note {font-size:x-small; font-style:italic}
  </STYLE>
<!--TOOLBAR_START-->
<!--TOOLBAR_EXEMPT-->
<!--TOOLBAR_END-->
</HEAD>

<XML id="source" src="authors.xml"></XML>
<XML id="stylesheet" src="hilite-xml.xsl"></XML>

<XML id="makeID">
  <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
    <xsl:template><xsl:eval>makeId(this)</xsl:eval></xsl:template>
    <xsl:script>
      function makeId(e)
      {
        if (e)
          return makeId(e.selectSingleNode("..")) +
            absoluteChildNumber(e) + (e.nodeType == 2 ? "@" : "_");
        else
          return "";
      }
    </xsl:script>
  </xsl:stylesheet>
</XML>

<SCRIPT>
  function doQuery(theQuery)
  {
     xmlSrc.innerHTML = result;
     var q = source.selectNodes(theQuery);
    for (var e = q.nextNode(); e != null; e = q.nextNode())
    {
      eID = e.transformNode(makeID.XMLDocument);
      document.all.item(eID).style.backgroundColor = "yellow";
    }

  }

  function loadQuery()
  {
     var q = window.event.srcElement.innerText;
     qryIn.value = q;
     doQuery(q);
  }

</SCRIPT>

<SCRIPT FOR="window" EVENT="onload">
  result = source.transformNode(stylesheet.XMLDocument);
   xmlSrc.innerHTML = result;
</SCRIPT>

<BODY>
<DIV class=note>Simple demonstration of performing queries against an XML document using XSL Patterns.</DIV>

<DIV class=heading>XSL Pattern:</DIV>
<INPUT ID=qryIn SIZE=60 TYPE=TEXT>
<INPUT TYPE="BUTTON" VALUE="Select Nodes" onClick="doQuery(qryIn.value)" id=BUTTON1 name=BUTTON1>
<BR>

<TABLE>
<TR>
<TD VALIGN="top">
<DIV class=heading>Some Sample Queries:</DIV>
<DIV class=sample onclick="loadQuery()">authors</DIV>
<DIV class=sample onclick="loadQuery()">authors/author</DIV>
<DIV class=sample onclick="loadQuery()">authors/author/name</DIV>
<DIV class=sample onclick="loadQuery()">authors/*/name</DIV>
<DIV class=sample onclick="loadQuery()">authors/author/*</DIV>
<DIV class=sample onclick="loadQuery()">authors/author[nationality]/name</DIV>
<DIV class=sample onclick="loadQuery()">authors/author[nationality='Russian']/name</DIV>
<DIV class=sample onclick="loadQuery()">authors/author[@period="classical"]</DIV>
<DIV class=sample onclick="loadQuery()">authors/author/@period</DIV>

</TD>
<TD VALIGN="top">
<DIV class=heading>XML source document</DIV>
<SPAN id=xmlSrc></SPAN>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>

Other Resources Other Resources

XML Path Language (XPath) Version 1.0


Introduction to the XPath Tree Model

XPath treats an XML document as a tree of interrelated branches and nodes, where a node can be nearly anything in the document: an element, attribute, processing instruction (PI), comment, text, or namespace, as well as the document itself. This tree model is based not on the nodes in itself, but on the relationship of elements to one another, attributes to elements, and so on.

The concept of a node is important. XPath—and by extension, XSLT—does not provide direct access to tags, attributes, and other markup. It provides access to the logical nodes established by that markup.

XPath's view of this sample document is explored in the following topics, which are contained in this section:

  • Overview of XPath Axes and Node Relationships
  • Determining the Name and String Value of a Node
  • Sample Tree for the Document Root
  • Sample Document Root Element Sub-Tree

The topics in this section use this XML file: Sample XML File for XPath Tree Model.


Overview of XPath Axes and Node Relationships

In addition to knowing the seven types of nodes, you also need to understand the possible kinds of relationships between and among nodes in a document. Each relationship corresponds to what XPath calls an axis. For more information, see Using XPath Axes to Navigate through XML Data.

The terms used for the axes assume that the document tree represents a set of family relationships. The axes that can be expressed with XPath are:

  • Parent
  • Child
  • Ancestor
  • Descendant
  • Ancestor-or-self
  • Descendant-or-self
  • Preceding
  • Following
  • Preceding-sibling
  • Following-sibling
  • Self

Two additional relationships apply only to element nodes:

  • Attribute
  • Namespace

Parent

The parent node of an element, attribute, PI, comment, or text node is the element immediately "above" it in the tree—the element which contains it. For the root element, and any comments or PIs which precede or follow it, the parent is the root node. The root node itself has no parent. The parent of a namespace node is the element which declares it. In the document diagrammed above, for instance:

  • The parent of the <books> element is the root node.
  • The parent of each of the catnum attributes is the corresponding <book> element.
  • The parent of the comment, "Are we sure this guy's name is spelled right???" is the first <book> element.
  • The parent of both the <?xsl-stylesheet?> PI and the comment at the end of the document is the root node.

Child

A node's child is any node immediately below it in the hierarchy of a document's nodes, with some exceptions. The exceptions are that neither attribute nor namespace nodes are considered children of their respective elements. Therefore, if an XPath expression locates all children of a given element, it locates only elements, text nodes, PIs, and comments immediately subordinate to that element.

PIs and comments in the document prolog or following the root element are considered children of the root node, as is the root element.

In the document diagrammed above, for instance:

  • The children of the root node are the <?xsl-stylesheet?> PI, the root <books> element, and the comment which follows the root element's end tag.
  • The children of the <books> element node are the two <book> elements. Note that the catdate attribute is not considered a child of the <books> element node, despite the fact that <books> is considered catdate's parent.
  • The children of the first <book> element are the first <title> element, the comment "Are we sure this guy's name is spelled right???" and the first <author> element.
  • The second <title> element has only one child, the text node "For Love of a Toothpick."

Ancestor

An ancestor of any node in the tree is any node at a higher level in the tree than the node in question, including its parent. The root node has no ancestors; on the other hand, the root node is an ancestor of all other nodes in the tree.

For example, in the previous document diagrammed above:

  • The catdate attribute's ancestors are the <books> element and the root node.
  • The <?xml-stylesheet?> PI, the root <books> element, and the comment following the <books> element each has a single ancestor, the root node.
  • Ancestors of the text node "Frey, Jörg" are the second <author> element, the second <book> element, the root <books> element, and the root node.

Descendant

A descendant node is any node (including children) which is subordinate to a given node in the document tree. Everything in the document tree is a descendant of the root node, except the root node itself and any attribute or namespace nodes.

For example, in the document diagrammed earlier in this topic:

  • The catdate and catnum attributes have no descendants. (Attributes have no children.)
  • Descendants of the first <book> element are the first <title> element and its text node, "Jambing on the Trixles"; the comment, "Are we sure this guy's name is spelled right???"; and the first <author> element and its text node, "Randall, Tristan." Since an attribute is not considered a child of its defining element, the catnum="id2345" attribute is not a descendant of this <book> element (or indeed of anything else in the document).

Ancestor-or-self

Ancestor-or-self nodes of a given node in the tree include all ancestors of that node and the node itself. Therefore, although the root node has no ancestors, an XPath expression which locates the ancestor-or-self nodes of the root node will locate the root node itself.

Some examples from the document diagrammed in this topic are:

  • The ancestor-or-self nodes of the concluding comment include the root node and the comment itself.
  • The catdate attribute's ancestor-or-self nodes are the <books> element which defines it, the root node, and the catdate attribute itself.

Descendant-or-self

If a given node in the tree has any descendants, an XPath expression locating its descendant-or-self nodes will locate all those descendants, and the node itself. If it has no descendants, such an expression will locate only the node itself. Thus, given the document diagrammed in this topic:

  • The second <title> element's descendant-or-self nodes are its text node, "For Love of a Toothpick," and that <title> element itself.
  • The document's concluding comment has no descendants; therefore it has only a single descendant-or-self node, which is the comment itself.

Preceding

A preceding node, relative to a given node in the document tree, is any node which appears in the document before that node, except ancestors, attribute nodes, or namespace nodes. One way to think of this is that preceding nodes are those whose content occurs in its entirety before the start of the node in question. Since the root node contains all other nodes in the document, it will never be located among a given node's preceding nodes; likewise, the root node itself has no preceding nodes. Given the document diagrammed earlier in this topic, for example:

  • The root <books> element has only one preceding node, which is the <?xml-stylesheet?> PI.
  • Everything in the document (except the attributes and the document root node) is a preceding node relative to the concluding comment.
  • The first <author> element's preceding nodes are the comment, "Are we sure this guy's name is spelled right???", the first <title> element and its text node ("Jambing on the Trixles"), and the <?xml-stylesheet?> PI. Since they are ancestors of the first <author> element, the first <book> element, the root <books> element, and the root node all terminate after the first <author> element closes, therefore they are not among its preceding nodes.

Following

Following nodes are the reverse of preceding ones: They include any nodes (except descendant, attribute, and namespace nodes) which come after a given node. Since the root node contains all other nodes in the document, it is a following node of none of them, and itself has no following nodes.

Based on the document diagrammed in this topic, we can say:

  • The root <books> element has only one following node, which is the document's concluding comment.
  • The concluding comment has no following nodes.
  • The first <author> element's following nodes are the second <book> element (and all of the second <book> element's descendants) and the concluding comment. Because the text node "Randall, Tristan" is a descendant (specifically, a child) of the first <author> element, it is not considered a following node for that element.

Preceding-sibling

Sibling relationships in a family identify children of the same parent, relative to one another. Therefore preceding-sibling nodes are a subset of all siblings, including only those which appear in the document before the node in question. Since attribute and namespace nodes can never be child nodes, they can never be found among a given nodes' preceding-siblings.

Note XPath does not define a simple "sibling" relationship, only preceding-sibling and following-sibling.

For instance, referring to the document described earlier in this topic:

  • Each of the <author> elements has one preceding-sibling node, which is the respective <title> element. However, the first <author> element also has another preceding-sibling, which is the comment, "Are we sure this guy's name is spelled right???"
  • The root <books> element has one preceding-sibling, the <?xml-stylesheet?> PI.
  • The concluding comment has two preceding-siblings: the root <books> element and the <?xml-stylesheet?> PI.

Following-sibling

Among a given node's following-siblings, you will find all those nodes (except attribute and namespace nodes, which can never be child nodes) which share that node's parent and appear after the node in question in the document.

Note XPath does not define a simple "sibling" relationship, only preceding-sibling and following-sibling.

Examples from the document diagrammed earlier in this topic include:

  • Neither of the <author> elements has any following-sibling nodes.
  • The root <books> element has one following-sibling, which is the concluding comment.
  • The concluding comment has no following-siblings.

Self

In some cases, you need an XPath expression which locates only the node you're already dealing with. For such cases, XPath provides the "self relationship." Every node in any given document has, of course, one and only one self node.

Attribute

Since attributes can never be found among the parent, child, ancestor, descendant, preceding, following, preceding-sibling, or following-sibling nodes of a given node, how do you locate them with XPath? The answer lies in the special attribute relationship. An element's attribute nodes are any attributes which it declares, and only elements can have attribute nodes.

Note A PI's pseudo-attributes cannot be located this way.

Using the sample document diagrammed earlier in this topic, for instance:

  • Each of the <book> elements has a single attribute node, the respective catnum attribute.
  • The root <books> element likewise has one attribute node, the catdate attribute.
  • None of the other elements in this sample document have any attribute nodes.

Namespace

An element has a namespace node for every namespace which is in scope for it. Because namespaces are implicitly inherited by all elements descended from an element which declares a namespace, the following hold true:

  • An element may have a namespace node even if the element does not itself declare a namespace.
  • An element may have multiple namespace nodes, one corresponding to each namespace that it declares and one corresponding to each namespace declared by an ancestor element.

See Also

Sample XML File for XPath Tree Model


Determining the Name and String Value of a Node

Aside from a node's relationship to other nodes in the tree, XPath defines for each node a name and a string value, as follows:

Node Type | Name | String value
Document root | Empty string ("") | Concatenated value of text in all descendant element and text nodes
Element | Element name (expanded form including namespace URI, if any) | Concatenated value of text in all descendant element and text nodes
Attribute | Attribute name (expanded form, including namespace URI, if any) | Attribute value
Text | Empty string ("") | All text in that node (multiple end-of-line sequences normalized to single newline)
Processing-instruction | The PI's target | Everything in the PI except the PI target and the whitespace which follows it
Comment | Empty string ("") | All text between the opening <!-- and closing --> delimiters
Namespace | Namespace prefix (excluding ":"), or empty string ("") if no prefix declared for the namespace | The URI which is bound to the namespace

Using the sample XML document diagrammed earlier in this topic, sample node names and values would be:

For the document root node, its name is "" (empty string) and its string value is "Jambing on the TrixlesRandall, TristanFor Love of a ToothpickFrey, Jörg".
Note This is the concatenated value of all descendant element and text nodes.
  • The name of the first <author> element is "author"; its string value is "Randall, Tristan" (that is, the concatenated value of all descendant element and text nodes). Note that the name of any <author> element in a document will be "author"—only their positions in the tree, and perhaps their values, will distinguish them.
  • The name of the second catnum attribute is "catnum"; its string value is "id7823".
  • The first text node in the document is "" (empty string); its string value is "Jambing on the Trixles."
  • There is only one processing-instruction node in the sample document, whose name is "xml-stylesheet" and whose string value is "type='text/xsl' href='catalog.xsl'".
    Note Because the format of data in a PI, aside from the PI target itself, is unconstrained by the XML specification, the string value of that data will always be a single string—including any embedded quotation marks—even though "pseudo-attributes" (such as type and href here) look as though they can be could be somehow treated individually. Individual pseudo-attributes can be treated separately in XPath only by extracting substrings of the overall string value.
  • The name of the second comment node in the sample document is "" (empty string); its string value is "Reviewed by Catalog Department 2000-12-30 09:11:16".
  • There are no namespace nodes in the sample document. However, assume the <books> element included the following namespace declaration:
    xmlns:bookdat href="http://www.mycompany.com"

    Then for the <books> element and all elements and attributes descended from it, there would be a namespace node in effect, named "bookdat" and with a string value of "http://www.mycompany.com".

See Also

Sample XML File for XPath Tree Model | Processing Text Strings by Using String Functions


Sample XML File for XPath Tree Model

Topics in this section use this file.

XML File (booksxpath.xml)

<?xml version="1.0" ?>
<!DOCTYPE books [
<!ENTITY oumlaut "&#38;#246;">
]>
<?xml-stylesheet type="text/xsl" href="catalog.xsl" ?>
<books catdate="2000-12-31">
    <book catnum="id2345">
        <title>Jambing on the Trixles</title>
        <!-- Are we sure this guy's name is spelled right??? -->
        <author>Randall, Tristan</author>
    </book>
    <book catnum="id7823">
        <title>For Love of a Toothpick</title>
        <author>Frey, J&oumlaut;rg</author>
    </book>
</books>
<!-- Reviewed by Catalog Department 2000-12-30 09:11:16 -->


Sample Tree for the Document Root

At the most obvious structural level, the "tree" which XPath can wander through the Sample XML File for XPath Tree Model consists of the document prolog—the XML declaration, the document-type declaration, and the <?xml-stylesheet?> PI—the root element <books>, and the comment which follows the root element's end tag.

Schematically, this tree might be represented like this:

Each of these containers is referred to in XPath terms as a node, and a collection of nodes as a node-set. In the above figure, there are four nodes accessible to most XSLT processors, including the MSXML engine:

  • The document root node
  • The <?xml-stylesheet?> processing-instruction node
  • The <books> element node
  • The comment node following the <books> element
Note The XML declaration and the document-type declaration are not typically accessible. This is because by the time an XSLT processor gets access to the document tree, the document has been fully parsed; information in the XML and document-type declarations is assumed to be useful to the parser but not passed to a downstream application.

See Also

Sample XML File for XPath Tree Model


Sample Document Root Element Sub-Tree

If the diagrams in Sample Tree for the Document Root were all of the document's content that XPath exposed, quite a bit of content would still be inaccessible for linking or transforming purposes. Fortunately, there is also a sub-tree available within the <books> root element highlighted above.

Fully expanded, the <book> element's sub-tree looks like this:

Note For simplicity, the above diagram disregards the newline characters following each element's end tag. For more information, see Controlling White Space with XSLT.

Like the full document tree shown in the preceding section, this sub-tree consists of a number of nested containers. While there is no Processing Instruction node type in this sub-tree, there could be; in addition, it shows the following node types:

  • element nodes (outlined in black), such as <books> itself, <book>, <title>, and <author>
  • attribute nodes (red), catdate and catnum
  • text nodes (blue), such as "Randall, Tristan" and "For Love of a Toothpick"
  • comment nodes (green), of which there is only one here
Note The text node showing the name of the author of "For Love of a Toothpick." In the tree it appears as "Frey, Jörg" with the entity substitution made. As with the XML and document-type declarations, entity declarations are invisible to XPath and XSLT processors; all that these processors see is the complete document as parsed, including the expanded form of entities.

A seventh node type, namespace nodes, may or may not be present in a document. A namespace node consists of a prefix and a URI to which the prefix is bound, and "exists" implicitly for any element or attribute node within the scope of the element which declares the namespace prefix. The xml: prefix is by default in effect for all XML documents.

See Also

Sample XML File for XPath Tree Model


Basic Syntax of XPath Expressions

This section covers the following:

  • Overview of XPath Syntax
  • Constructing an XPath Location Step
  • Constructing the Node-Test Portion of a Location Step
  • Specifying the Axis Portion of a Location Step
  • Constructing the Predicate Portion of a Location Step


Overview of XPath Syntax

An XPath expression consists of a series of one or more location steps, separated by "/" delimiters; together, these steps are referred to as the location path. So a location path consisting of two location steps looks like:

locationstep/locationstep

Each location step, from left to right, relocates you up or down in the document's tree of nodes relative to the location step(s) preceding it, if any.

A location step can be absolute or relative. Absolute location steps can never appear in the location path in any but the leftmost position. Relative location steps can appear anywhere in the location path.

Location paths can be compound—that is, you can construct a location path which will select any nodes matching any of a group of constituent location paths. To do so, separate the location paths with a pipe character, |. For example:

locationpath1 | locationpath2

says to locate all nodes in the target document on either locationpath1 or locationpath2.

Some sample absolute location paths and their interpretations are provided in the following table.

Location path | Description
/ | Locates the document root
/books | Locates all <books> children of the document root
/descendant::title | Locates all <title> elements in the document (i.e., descended from the document root)
/comment() | /text() | Locates all comments and text nodes in the document
/processing-instruction("xml-stylesheet") | Locates any PI whose target is "xml-stylesheet".

Absolute Location Steps

An absolute location step in an XPath expression assumes that the content will be located "starting from scratch" within the target document. It always begins with a "/" delimiter, whose presence is interpreted to mean, "Start at the document's root node."

Relative Location Steps

The starting point for a relative location step is always considered to be some previously established context node. This context node may be identified by an absolute location step, or, if the context node within the target document has already been set, by some relative location step. For more information, see Context and Navigation in XPath.


Constructing an XPath Location Step

A location step is constructed as follows:

axis::nodetest[predicate]

Each of the three components may or may not be present in a given expression. The expression as a whole is evaluated as a series of successively finer-grained sieves, resulting in the selection of one or more nodes from the target document:

  • The axis (separated from the node-test, if there is one, by a pair of colons, ::) establishes a "direction to look," beginning at each of the nodes selected by the node-test. There is an axis corresponding to each type of relationship defined by XPath's tree model.
  • The node-test determines the initial set of nodes to be selected.
  • The predicate is set off from the node-test and axis, if they are present, by square bracket characters, [ and ]. If a predicate is present, it defines conditions to be met in order for a given node to be ultimately selected by the XPath expression.
Note The result of selecting by location step, even if all three components are present, does not necessarily mean that only one node will be located.

Some sample location steps using the complete syntax are shown in the following table.

Location step | Description
child::*[position()=1] | Locates the first child node of the context node
ancestor-or-self::book[@catdate="2000-12-31"] | Locates all ancestors of any <book> child of the context node, as well as the <book> child itself, as long as the element in question has a catdate attribute with the value "2000-12-31".
//self::parent[name()="book"] | descendant::node[name()="author"] | Locates any node in the document whose parent node is named "book," or any node descended from the context node whose name is "author".

Example

This example does not generate significant output. It demonstrates that no errors are generated by the above XPath expressions.

XML File (booksxpath.xml)

Use the Sample XML File for XPath Tree Model and change its href attribute to point to booksxpath.xsl.

XSLT File (booksxpath.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="//book">
   <p/>child::*[position()=1] --
      <xsl:value-of select="child::*[position()=1]"/>
   <p/>ancestor-or-self::book[@catdate="2000-12-31"]/author --
      <xsl:value-of select='ancestor-or-self::book[@catdate="2000-12-31"]/author'/>
   <p/>//self::parent[name()="book"] | descendant::node[name()="author"] --
      <xsl:value-of select='//self::parent[name()="book"] | descendant::node[name()="author"]'/>
</xsl:template>

</xsl:stylesheet>


Constructing the Node-Test Portion of a Location Step

The node-test portion of a location step identifies the type of node(s), or the specific node(s), which make up the baseline collection of nodes from which to gather possible matches. It takes three possible forms:

  • Use a node name to select nodes with that name.
  • Use a node type, followed by empty parentheses, (), to select nodes of that type. The following node types are available:
    • comment() selects element nodes;
    • text() selects attribute nodes;
    • processing-instruction() selects PI nodes;
    • and node() selects nodes of any kind.
  • Use processing-instruction("target") to select PIs with a particular target.

See Also

Constructing the Node-Test Portion of an XPath Expression


Specifying the Axis Portion of a Location Step

The axis portion of an XPath location step specifies, like the axis of a two-dimensional graph, the direction in which to locate something relative to some starting point. There is an axis corresponding to each of the basic XPath tree model relationships:

  • parent::
  • child::
  • ancestor::
  • descendant::
  • ancestor-or-self::
  • descendant-or-self::
  • preceding::
  • following::
  • preceding-sibling::
  • following-sibling::
  • self::
  • attribute::
  • namespace::

See Also

Using XPath Axes to Navigate through XML Data


Constructing the Predicate Portion of a Location Step

The final possible component of an XPath location step, called the predicate, provides a further, finer-grained filter to select among the node(s) located by the node-test and axis. The basic form of a predicate is:

[something operator somevalue]

where:

  • the square brackets, [ and ], are required;
  • something may be either a further location step, relative to the nodes matched so far by the node-test and axis, or a built-in XPath function;
  • operator is one of several Boolean operators, such as an equals sign or "!=" for a "does not equal" condition; and
  • somevalue is the value to which you want to compare something.

For instance:

[position() = 1]

locates the first matching node in document order, while:

[attribute::empid != "73519"]

locates the subset of the matching node-set at that point which includes any nodes with an empid attribute whose string value does not equal "73519".

Note Be careful when using the "<" and ">" operators in your XPath expressions. Because these characters are significant in markup, you will typically have to escape them using the &lt; and &gt; entity references. For example:

[attribute::empid &lt;= "69999"]
says to select all nodes with an empid attribute whose value is <= (less than or equal to) "69999".

White space between the terms of a predicate is not significant. That is:

[position() = 1]

and

[position()=1]

function identically.

See Also

Filtering XML Data Using XPath Predicates


Differences between XPath Expressions and XSLT Patterns

An XSLT pattern may appear in a number of places in a style sheet:

  • As the value of the match attribute of an <xsl:template> element. (This is the most common use of XSLT patterns.)
  • As the value of the match attribute of an <xsl:key> element.
  • As the values of the count and from attributes of an <xsl:number> element.

The purpose of a pattern is to restrict the set of candidate nodes in a node-set to just those nodes that meet a particular condition, or set of conditions. For instance:

<xsl:template match="//attribute::invoice_num[.='X00456']">

restricts the candidate nodes for the template rule just to the element(s) with an invoice_num attribute whose value is "X00456". This works even though from any given context node, in theory all other nodes in the documents are reachable candidates.

All XSLT patterns are also XPath expressions. However, the reverse is not always true: not all XPath expressions are XSLT patterns. For instance:

round(sales)

is a legitimate XPath expression, which returns the value of the <sales> element rounded to the nearest integer. But:

<xsl:template match="round(sales)">

is not a legitimate way to open an XSLT <xsl:template> element. Even though it refers to a node-set (sales) relative to the context node, taken as a whole the expression does nothing to constrain the universe of all possible candidate nodes at that point to a subset of them. Thus, such XPath expressions must always appear in a pattern in some other form, such as within a predicate.

For example, we could use the round(sales) expression in this way in an XSLT pattern:

<xsl:template match=".//*[round(sales) &lt; 5000]">

This says to restrict the universe of possible candidate nodes to those which are descended from the context node (.//), with any name (*), whose <sales> children have a value less than 5000 ([round(sales) &lt; 5000]).


Context and Navigation in XPath

The following section covers evaluating, setting, and changing the context in which an XPath expression, or where succeeding an XPath expressions is evaluated.

  • How XSLT Defines the Context for XPath Expressions
  • How the DOM Defines the Context for XPath Expressions
  • Constructing an XPath Expression
  • Constructing the Node-Test Portion of an XPath Expression
  • Determining the Current Context in an XSLT Application
  • Determining the Context Node
  • Determining the Context Size
  • Determining the Context Position
  • Determining the Current Node
  • Understanding How the Context Node Changes
  • How XSLT Template Rules Depend on Context
  • Sample XML Data File for XPath Context and Navigation


How XSLT Defines the Context for XPath Expressions

At run-time, templates in a style sheet are associated with specific source nodes, starting with the document root node that is associated with the root template (match="/"). Within the template, the associated source node is referred to as the current node. The current node defines a context for evaluating the XML Path Language (XPath) expressions that are within the template.

XPath expressions are accepted as attribute values for <xsl:value-of>, <xsl:for-each>, <xsl:apply-templates>, <xsl:if>, <xsl:when>, <xsl:copy-of>, <xsl:param>, <xsl:sort>, <xsl:variable>, <xsl:with-param>, and <xsl:template>. The attribute names define how the context for the query is determined and whether it results in a new context.

Context for Select Expressions

The <xsl:value-of>, <xsl:for-each>, <xsl:copy-of>, <xsl:param>, <xsl:sort>, <xsl:variable>, <xsl:with-param>, and <xsl:apply-templates> elements have a select attribute. This expression is evaluated relative to the template's current node. In <xsl:for-each> or <xsl:apply-templates>, the select returns a node-set, and each node in this set becomes the current node for further queries within it.

The following example shows <xsl:for-each> and <xsl:value-of> elements are used in a simplified snippet from invoice.xsl (in Sample XSLT File for DOM Context).

<TABLE BORDER="1">
  <xsl:for-each select="invoices/invoice">
    <TR>
      <TD>Invoice #<xsl:value-of select="@id"/></TD>
    </TR>
    <xsl:for-each select="items/item">
      <TR>
        <TD><xsl:value-of select="qty"/></TD>
        <TD><xsl:value-of select="description"/></TD>
        <TD>$<xsl:value-of select="price"/></TD>
      </TR>
    </xsl:for-each>
  </xsl:for-each>
</TABLE>

The first <xsl:for-each> selects a set of "invoice" elements, each of which becomes the context for the "items/item" query. Each "item", in turn, becomes the context for the various queries in the <xsl:value-of> elements.

Each node selected by <xsl:apply-templates> is associated with a template and therefore, becomes the current node for the template.

Because each expression defines a new context, a set of nested queries, such as those in the preceding example, produces a set or "path" of context nodes active at one time. xmconPlacingItemsintoaGridxmconCreatingCommaSepList

Context for Test Boolean Expressions

The conditional elements <xsl:if> and <xsl:when> do not define a new context for queries within themselves because they do not actually select new nodes. They just test to make sure the nodes are there. In the following example, the <xsl:for-each select="price"> query is relative to "item" elements, despite the intervening conditional that tests the "qty" value:

<TABLE>
  <xsl:for-each select="items/item">
    <TR>
      <TD>
        <xsl:value-of select="qty"/>
      </TD>
      <TD>
        <xsl:value-of select="description"/>
      </TD>
      <TD>
        $<xsl:value-of select="price"/>
      </TD>
      <TD> <!-- 10% volume discount -->
        <xsl:if test="qty[.>=10]">
          <xsl:for-each select="price">
            <xsl:value-of select="formatNumber(.*.10, '$#,##0.00')"/>
          </xsl:for-each>
        </xsl:if>
      </TD>
      <TD STYLE="text-align:right"> <!-- line total -->
        <xsl:value-of select="formatNumber(user:lineTotal(.), '$#,##0.00')"/>
      </TD>
    </TR>
  </xsl:for-each>
</TABLE>

Context for Match Patterns

The <xsl:template> element has a match attribute that accepts a pattern for the purposes of matching templates to specific elements; there is no fixed context for a query in this case. For more information, see Defining Match Patterns in <xsl:template>.

The preceding code listings are from the Invoice sample. For more information, see Sample XML File for DOM Context.


How the DOM Defines the Context for XPath Expressions

The Microsoft XML Parser (MSXML) implementation contains methods that accept an XML Path Language (XPath) string to identify nodes within the XML tree. The selectNodes method returns a node list pointing to each of the selected nodes, as in the following example.

items = xmldoc.selectNodes("invoices/invoice/items/item");

It takes a substantial amount of code to retrieve the "item" nodes by navigating the tree. With the selectNodes method and XPath expressions, nodes can be retrieved through a single line of code.

In most cases, the returned set of nodes are iterated over to perform further manipulations. The following example shows how you can calculate a total price for an "invoice" element.

function invoiceTotal(invoice)
  {
    invoice = invoice.nextNode()
    items = invoice.selectNodes("items/item");
    var sum = 0;
    for (var item = items.nextNode(); item; item = items.nextNode())
    {
      var price = item.selectSingleNode("price").nodeTypedValue;
      var qty = item.selectSingleNode("qty").nodeTypedValue;
      if (qty >= 10)
        price = 0.9*price;
      sum += price * qty;
    }
    return sum;

This example contains two query contexts. The first query is performed from the context of the "invoice" element, and the query string reflects this by beginning with the document element "items." The for loop repeat through the returned nodes and uses each as a context for further queries. These query strings are relative to "item" elements, and look within them for the "price" and "qty" children. This illustrates that the node on which the selectNodes is performed defines the context for the query.

Performing queries from the document root versus the document element can be confusing. These two nodes are different in the XML tree and therefore require different query strings. The following three statements yield identical results for the sample document, although only the last two are logically equivalent.

items = xmldoc.selectNodes("invoices/invoice");
items = xmldoc.selectNodes("*/invoice");
items = xmldoc.documentElement.selectNodes("invoice");

The selectSingleNode method returns the first node that matches the query, providing a convenient way to return a node directly without extracting it from a NodeList. It is equivalent to "selectNodes(pattern).item(0)". The preceding example could simplify the code by using the selectSingleNode method.

function invoiceTotal(invoice)
{
  invoice = invoice.nextNode()
  items = invoice.selectNodes("items/item");
  var sum = 0;
  for (var item = items.nextNode(); item; item = items.nextNode())
  {
    var price = item.selectSingleNode("price").nodeTypedValue;
    var qty = item.selectSingleNode("qty").nodeTypedValue;
    sum += price * qty;
  }
  return sum;
}

In the preceding example, selectNodes is used to select a set of "item" elements. When only a single node is expected, such as the "price" and "qty" elements, selectSingleNode can be used.

The preceding sample code is part of the Invoice sample. For more information, see Sample XML File for DOM Context.


Sample XML File for DOM Context

This file is part of the Invoice sample.

XML File (invoice.xml)

<?xml version="1.0" encoding="windows-1252"?>
<?xml-stylesheet type="text/xsl" href="invoice.xsl"?>
<invoices xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <customers>
    <customer id="2513">Joe</customer>
    <customer id="4871">Bob</customer>
    <customer id="7806">Jane</customer>
    <customer id="1579">Bruce</customer>
    <customer id="2533">John</customer>
    <customer id="1445">Bill</customer>
  </customers>
  <invoice id="5034">
    <customer ref="2513"/>
    <items>
      <item>
        <product-number>50014371</product-number>
        <description>Windbreaker (teal)</description>
        <qty dt:dt="number">1</qty>
        <price dt:dt="number">18.00</price>
      </item>
    </items>
  </invoice>
  <invoice id="5035">
    <customer ref="4871"/>
    <items>
      <item>
        <product-number>61570910</product-number>
        <description>Arctic Parka</description>
        <qty dt:dt="number">1</qty>
        <price dt:dt="number">160.00</price>
      </item>
      <item>
        <product-number>ISBN:1-57231-686-1</product-number>
        <description>Signal Flare 6-pack</description>
        <qty dt:dt="number">3</qty>
        <price dt:dt="number">48.50</price>
      </item>
      <item>
        <product-number>68710047</product-number>
        <description>Woolen Mittens</description>
        <qty dt:dt="number">1</qty>
        <price dt:dt="number">14.50</price>
      </item>
    </items>
  </invoice>
  <invoice id="5036">
    <customer ref="7806"/>
    <items>
      <item>
        <product-number>56812007</product-number>
        <description>Tropical Shade Hat</description>
        <qty dt:dt="number">1</qty>
        <price dt:dt="number">29.90</price>
      </item>
      <item>
        <product-number>74500231</product-number>
        <description>Bug Repellant</description>
        <qty dt:dt="number">3</qty>
        <price dt:dt="number">4.95</price>
      </item>
    </items>
  </invoice>
  <invoice id="5037">
    <customer ref="1579"/>
    <items>
      <item>
        <product-number>65040097</product-number>
        <description>Arctic Parka</description>
        <qty dt:dt="number">2</qty>
        <price dt:dt="number">160.00</price>
      </item>
      <item>
        <product-number>2310078</product-number>
        <description>Tundra Jacket</description>
        <qty dt:dt="number">1</qty>
        <price dt:dt="number">105.50</price>
      </item>
    </items>
  </invoice>
  <invoice id="5038">
    <customer ref="2533"/>
    <items>
      <item>
        <product-number>54807910</product-number>
        <description>DVD Player</description>
        <qty dt:dt="number">1</qty>
        <price dt:dt="number">342</price>
      </item>
      <item>
        <product-number>77842448</product-number>
        <description>Oddesy Mousepad</description>
        <qty dt:dt="number">1</qty>
        <price dt:dt="number">15</price>
      </item>
    </items>
  </invoice>
  <invoice id="5039">
    <customer ref="1445"/>
    <items>
      <item>
        <product-number>65470025</product-number>
        <description>Adventure Rations (Tofu)</description>
        <qty dt:dt="number">20</qty>
        <price dt:dt="number">6.00</price>
      </item>
      <item>
        <product-number>65470025</product-number>
        <description>Adventure Rations (Chicken)</description>
        <qty dt:dt="number">20</qty>
        <price dt:dt="number">6.00</price>
      </item>
      <item>
        <product-number>24500358</product-number>
        <description>Adventure Rations (Beef)</description>
        <qty dt:dt="number">20</qty>
        <price dt:dt="number">6.00</price>
      </item>
    </items>
  </invoice>
</invoices>


Sample XSLT File for DOM Context

This file is part of the Invoice sample.

XSLT File (invoice.xsl)

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:msxsl="urn:schemas-microsoft-com:xslt"
        xmlns:user="mynamespace"
        version="1.0">
  <xsl:template match="/">
    <HTML>
      <STYLE>
        TD {font-size:9pt}
      </STYLE>
      <BODY STYLE="font:9pt Verdana">
        <H3>Invoices</H3>
        <TABLE BORDER="1">
          <TR>
            <TD><B>Qty</B></TD>
            <TD><B>Description</B></TD>
            <TD><B>Price</B></TD>
            <TD><B>Discount</B></TD>
            <TD><B>Total</B></TD>
          </TR>
          <xsl:for-each select="invoices/invoice">
                  <xsl:variable name="customer-id" select="./customer/@ref"/>
            <TR>
              <TD COLSPAN="5" STYLE="border:none; background-color:#DDDDDD">
                Invoice #<xsl:value-of select="@id"/>,
                for customer: <xsl:value-of select="/invoices/customers/customer[@id=$customer-id]"/>
              </TD>
            </TR>
            <xsl:for-each select="items/item">
                     <TR>
                <TD>
                  <xsl:value-of select="qty"/>
                </TD>
                <TD>
                  <xsl:value-of select="description"/>
                </TD>
                <TD>
                  $<xsl:value-of select="format-number(price,'#,##0.00')"/>
                </TD>
                <TD> <!-- 10% volume discount -->
                  <xsl:if test="qty[. &gt;= 10]">$<xsl:value-of select="format-number(price * .10,'##0.00')"/></xsl:if>
                </TD>
                <TD STYLE="text-align:right"> <!-- line total -->
                           <xsl:choose>
                           <xsl:when test="qty[. &gt;= 10]">
                              $<xsl:value-of select="format-number((price * .90) * qty,'#,##0.00')"/>
                           </xsl:when>
                           <xsl:otherwise>
                              $<xsl:value-of select="format-number(price * qty,'#,##0.00')"/>
                           </xsl:otherwise>
                           </xsl:choose>
                </TD>
              </TR>
            </xsl:for-each>
            <TR>
              <TD COLSPAN="4"></TD>
              <TD STYLE="text-align:right; border:none; border-top:1px solid black">$<xsl:value-of select="format-number(user:invoiceTotal(.),'#,##0.00')"/>
              </TD>
            </TR>
            <TR/>
          </xsl:for-each>
        </TABLE>
      </BODY>
    </HTML>
  </xsl:template>

    <msxsl:script implements-prefix="user"><![CDATA[
    function invoiceTotal(e)
    {
     var invoice = e.nextNode();
     var items = invoice.selectNodes("items/item");
      var sum = 0;
      for (var item = items.nextNode(); item; item = items.nextNode())
      {
        var price = item.selectSingleNode("price").nodeTypedValue;
        var qty = item.selectSingleNode("qty").nodeTypedValue;
        if (qty >= 10)
          price = 0.9*price;
        sum += price * qty;
      }
      return sum;
    }
  ]]></msxsl:script>
</xsl:stylesheet>


Microsoft XML 4.0 Technology Preview - XSLT Reference

Sample Formatted Output for DOM Context


Constructing an XPath Expression

A full XPath location path is made up of one or more location steps, separated from one another by a slash character, /. Therefore, if a location path consisted of three location steps, it looks like the following:

locationstep/locationstep/locationstep

Each location step follows this general format:

axis::nodetest[predicate]

The axis, together with the ::, is optional. It indicates the general direction from the context node in which the location step proceeds. For example, the child:: axis says that the remainder of this location step considers only child nodes of the context node; ancestor:: looks at all ancestor nodes of the context node; and so on. If omitted, axis:: defaults to child::. Several axes also have shortcut forms; for instance, the @ character is a shortcut for the attribute:: axis.

For more information, see Using XPath Axes to Navigate through XML Data.

The nodetest indicates which node(s), from among all nodes on the indicated axis, are to be considered candidate, that is, potential, matches for the location step. Typically, the node test is the name of a node, such as an element name. For example:

ancestor::para

locates all <para> elements which are ancestors of the context node.

For more information, see Constructing the Node-Test Portion of an XPath Expression.

Finally, the predicate provides a "filter," specifying a selection criterion for further refining the list of candidate nodes. The predicate is optional, if it is omitted, the square bracket characters, [ and ], are also omitted. A complete location step, including a predicate, might be:

ancestor::para[@class="open"]

This locates all <para> elements which are ancestors of the context node and which have a class attribute whose value is "open". That is, all <para> ancestors of the current node which have any other value for their class attribute, or no class attribute at all, will be excluded from those selected by this location step.

For more information, see Filtering XML Data Using XPath Predicates.

Each succeeding location step moves you further down or up the document tree relative to the location step preceding it. This enables quite complex location paths to be built up, each component selecting further refinements to the set of matching nodes. For example:

ancestor::para[@class="open"]/descendant-or-self::*[position() &lt;= 7]

This complete location path might be read as follows:

  • First location step: Beginning at the context node, look "up the tree," that is, along the ancestor:: axis. From among the nodes you can see along this axis, select all <para> elements whose class attributes equal "open".
  • Second location step: From among the nodes selected by the first location step, look down the tree, including each of those nodes previously selected, that is, look along the descendant-or-self:: axis. From among all the nodes you see along this axis, regardless of the node's name, that's the "*" node test, select only the first seven in document order, the [position() &lt;= 7] predicate.

Further location steps could be added to refine the XPath expression even more. In short, the XPath syntax provides you with the power to locate nodes in an XML document, from any other.

Example

The following example does not generate significant output. It demonstrates that no errors are generated by the above XPath expressions.

XSLT File (xptest.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="//book">
   <p/>ancestor::para --
      <xsl:value-of select='ancestor::para'/>
   <p/>ancestor::para[@class="open"] --
      <xsl:value-of select='ancestor::para[@class="open"]'/>
   <p/>ancestor::para[@class="open"]/descendant-or-self::*[position() &lt;= 7] --
      <xsl:value-of select='ancestor::para[@class="open"]/descendant-or-self::*[position() &lt;= 7]'/>
</xsl:template>

</xsl:stylesheet>

XML File (booksxpath.xml)

Use the Sample XML File for XPath Tree Model and change its href attribute to point to the above XSLT file.

See Also

Determining the Context Node

Other Resources Other Resources

XSL Developer's Guide Samples


Constructing the Node-Test Portion of an XPath Expression

The node test is the only required portion of an XPath location step. As such, understanding it is critical to successfully employing XPath expressions.

For each axis, there is a principal node type which determines the class of nodes which will be considered when looking along that axis. The rule of thumb is that if an axis can contain elements, then the principal node type is element. Otherwise, the principal node type is whatever type of node is specified by the axis. Therefore, the principal node type is an element for all axes, but attribute:: and namespace::; for those two axes, the principal node type is an attribute and namespace, respectively.

There are three general types of node test:

  • Name tests
  • Node-type tests
  • Tests for a specific processing instruction

These node tests are described below.

Name tests

Most common the name tests, consists of the name of the nodes you are interested in.

For instance, you can locate all <forecast> elements in the sample XML document with this name test:

/descendant::forecast

This directs the XPath application to start at the document root (/), look at all its descendants, and select those descendants named "forecast". Because the descendant:: axis is specified, and because the principal node type for the descendant:: axis is element, only elements named "forecast" are considered. An PI whose target was "forecast" would not be located.

Similarly,

attribute::day

locates the day attribute of the context node. If the context node is one of the <forecast> elements, this location step points to its day attribute. Otherwise, the result of this location step is an empty node-set.

In place of a specific name, you can also use an asterisk, *, to locate all named nodes along that axis regardless of their names. For example:

descendant::*

locates all elements descended from the context node. If the context node is the root <weather> element, this XPath expression would locate a node-set consisting of all elements in the document except the <weather> element itself. Similarly,

namespace::*

returns all namespace nodes in effect for the context node.

Node-type tests

When you're interested in selecting nodes of a particular type other than, or in addition to elements, use a node type followed by an empty pair of parentheses, (). There are four node types available:

  • comment() selects comment nodes.
  • text() selects text nodes.
  • processing-instruction() selects PIs.
  • node() selects all nodes, regardless of their type.
Note The parentheses, (), serve one important purpose: They eliminate the problem that may arise if the source document has nodes whose names are comment, text, processing-instruction, or node. When the XPath application sees the double parentheses, it knows that this is a node-type test, not a test for nodes with these names. Also note that these are not XPath functions, references to which also contain parentheses, empty or otherwise.

The effect of using a node-type test is to override the principal node type for the given axis. For example, descendant::text() locates all text nodes descended from the context node, even though the principal node type for the descendant:: axis is element.

The follow examples:

/descendant::comment()

selects all comments in the document, both the one preceding the root <weather> element and the one which says "No precipitation today."

/descendant::forecast/descendant::text()

selects all the text nodes descended from the two <forecast> elements.

/processing-instruction()

selects the <?xml-stylesheet?> processing instruction.

/descendant-or-self::node()

selects all nodes in the document, except attributes that are never considered descendants.

Tests for specific processing instruction

You can also locate all processing instructions with a specific target, using the general form:

processing-instruction("target")

The example document has only one processing instruction. If it included more than one, you could locate just the one specifying an XSLT style sheet as follows:

/child::processing-instruction("xml-stylesheet")
Note if the document included more than one PI with the same target, this would return a node-set consisting of all PI nodes with that target, not just a single PI node.

Example

The following example does not generate significant output. It demonstrates that no errors are generated by the preceding XPath expressions.

XML File (weather.xml)

Change the href attribute in weather.xml (shown in Sample XML Data File for XPath Context and Navigation) to reference xpnodetst.xsl.

XSLT File (xpnodetst.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="//weather">
   <p/>/descendant::forecast --
      <xsl:value-of select='/descendant::forecast'/>
   <p/>attribute::day --
      <xsl:value-of select='attribute::day'/>
   <p/>attribute::day --
      <xsl:value-of select='attribute::day'/>
   <p/>descendant::* --
      <xsl:value-of select='descendant::*'/>
   <p/>namespace::* --
      <xsl:value-of select='namespace::*'/>
   <p/>/descendant::comment() --
      <xsl:value-of select='/descendant::comment()'/>
   <p/>/descendant::forecast/descendant::text() --
      <xsl:value-of select='/descendant::forecast/descendant::text()'/>
   <p/>/processing-instruction() --
      <xsl:value-of select='/processing-instruction()'/>
   <p/>/descendant-or-self::node() --
      <xsl:value-of select='/descendant-or-self::node()'/>
   <p/>/child::processing-instruction("xml-stylesheet") --
      <xsl:value-of select='/child::processing-instruction("xml-stylesheet")'/>

</xsl:template>

</xsl:stylesheet>

See Also

Sample XML Data File for XPath Context and Navigation | Constructing the Node-Test Portion of a Location Step | Basic Syntax of XPath Expressions | Using XPath Axes to Navigate through XML Data | Using Functions in XPath Expressions


Determining the Current Context in an XSLT Application

Any XPath expression referencing some nodes in a source document is evaluated according to conditions that are true at the time the evaluation occurs. When XPath is being used for a linking application, the context in most cases will not change; each link carries its own context with it. In XSLT applications, however, understanding the context is critical because a number of factors may cause the context to change at various points in the style sheet.

There are two general kinds factorsof: static and dynamic.

Static context

The static context includes two general conditions that are true depending on the XPath expression's placement in the style sheet.

  • Namespaces: A given XPath expression found at two different points in the style sheet may have two completely different meanings if the namespaces in effect at those two points are different.
  • Variable declarations: An XPath expression , if it refers to a variable, correctly interpreting the expression depends on the declaration of that variable.

Dynamic context

The dynamic context does not depend on the location of the XPath expression in the style sheet, but on the state of processing at the time the expression is evaluated. Four factors are included in the dynamic context: the context node, context size, context position, and current node.

See Also

Using XSLT Variables and Parameters | Determining the Context Node | Determining the Context Size | Determining the Context Position | Determining the Current Node


Determining the Context Node

The context node of an XPath relative location path is the node relative to the expression being evaluated.

Note In lengthy XPath expressions, the context node implicitly changes as the processor hits various steps in moving along the expression from left to right. For example, consider the expression:
attribute::scale/ancestor::weather/forecast[position()=2]/attribute::day
  • When evaluation of the expression begins, the context node is the parent element of a scale attribute.
  • The /ancestor::weather term is evaluated in terms of the scale attribute.
  • /forecast[position()=2] assumes the context node to be the result of the previous location step, that is, in the case of the sample document, the second <forecast> child of the <weather> element.
  • /attribute::day locates the day attribute of the elements resulting from the previous step.

For XSLT, understanding the context node, and knowing what it is at any given point, is critical to successful use of the standard.

Example

The XPath expressions are highlighted in this XSLT file.

What is displayed in the result tree by this template rule depends entirely on the context node. The template rule matches a single element type in the source tree, <temperature>, and the corresponding match pattern (match="temperature") is what establishes the context node within the body of the template rule. However, the <temperature> element type can be a child of either the <today> element or a <forecast> element, and the <xsl:choose> element operates accordingly:

  • Is the parent element named "today"? (This is the test="name(..)="'today'" attribute in the <xsl:when> element.) If so, just output "Today's temperature:" and the value of the <temperature> element itself.
  • If the parent element is not named "today"—this is the <xsl:otherwise> element's role—then output the word "Today," the value of that parent element's day attribute (e.g. "+1"), and the string "'s temperature: ".

If the context node did not change each time this template rule fired, it would not be possible to produce different output for each occurrence of the <temperature> element.

XML File (weather.xml)

Change the href attribute in weather.xml (shown in Sample XML Data File for XPath Context and Navigation) to reference weathersimple.xsl.

XSLT File (weathersimple.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="temperature">
    Today<xsl:choose>
        <xsl:when test="name(..)='today'">'s </xsl:when>
        <xsl:otherwise ><xsl:value-of select="../@day" />'s </xsl:otherwise>
    </xsl:choose>
temperature: <xsl:value-of select="." /><br />
</xsl:template>

</xsl:stylesheet>

Formatted Output

Today's temperature: 76
Today+1's temperature: 81
Today+2's temperature: 72

Processor Output

<?xml version="1.0" encoding="UTF-16"?>
    Today's
temperature: 76<br />
    Today+1's
temperature: 81<br />
    Today+2's
temperature: 72<br />


Determining the Context Size

Many XPath expressions locate just a single node in the source tree. For example, referring to the sample XML document introduced earlier in this topic, this XPath expression:

today

locates just one element node.

However, in many other cases the XPath expression locates more than one node or rather, an indeterminate number of nodes, ranging from 0 on up — that is — a node-set. For example:

forecast

When applied to the sample document, it locates not just a single node but a node-set, and the size of that node-set—the number of nodes in it, or two in this case—can be critical in determining what your style sheet needs to do at a given point.

The context size is always accessible as the value of the XPath last() and count() functions, each returning an integer. Use last() when you are already working with the node-set in question. Use count() when you need to pass it to another node-set. This can be used for calculating the average of all temperatures in your sample weather-related XML document, when used in concert with the sum() function.

The last() and count() functions are useful in laying out tables whose number of columns, fare fixed but whose number of rows vary depending on the number of occurrences of some element in the source tree.

For more information about last() and count(), see Processing Node-Sets by Using Node-Set Functions. For more information about sum(), see Using Numeric Functions to Perform Math Operations in XPath.

Example

XML File (weather.xml)

Change the href attribute in weather.xml (shown in Sample XML Data File for XPath Context and Navigation) to reference weatherconsize.xsl.

XSLT File (weatherconsize.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="/">
Average temperature (for
<xsl:value-of select="count(.//temperature)"/> days) :
<xsl:value-of
select="sum(.//temperature) div count(.//temperature)"/> degrees
</xsl:template>

</xsl:stylesheet>

Formatted Output

Average temperature (for 3 days) : 76.33333333333333 degrees

Processor Output

<?xml version="1.0" encoding="UTF-16"?>
Average temperature (for
3 days) :
76.33333333333333 degrees


Determining the Context Position

Similar to context size, context position, where you are in the node-set, is as important in determining what a style sheet needs at any one time. A typical example can be performing an action for every Nth node.

You can use the Sample XML Data File for XPath Context and Navigation, to display information for each day on a separate line, coloring the odd lines white and the even lines yellow. This provides easy legibility when there are a large amount of data to be displayed. Use the following XSLT template rule to display just the temperature values:

The following template rule display just the temperature values:

  • The match pattern, match="weather/*", selects all children (*) of all children named "weather" of the context node, that is, of the document root node. Therefore, it selects a node-set consisting of the <today> element and the two <forecast> elements.
  • The template rule declares a local variable, called odd_or_even, whose value is either the "odd" or "even" string depending on the value of the position within the node-set of the node currently being processed.
  • The test uses the position() function, which returns an integer whose value is that of the current node's position in the node-set. The test calculates the remainder of this integer when divided by 2. If the result is 0, then the result of the test is true, and $odd_or_even is "even"; otherwise it is "odd".
  • The <xsl:choose> element that follows the variable's assignment tests the variable's value. If "odd," the temperature is inserted into a <p> element whose background-color is white; otherwise, the <p> element's background-color will be yellow.
Note The use of the position() function in the <xsl:variable> code.

For more information about position(), see Processing Node-Sets by Using Node-Set Functions.

Example

XML File (weather.xml)

Change the href attribute in weather.xml (shown in Sample XML Data File for XPath Context and Navigation) to reference weathercontextposn.xsl.

XSLT File (weathercontextposn.xsl)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="weather/*">
    <xsl:variable name="odd_or_even">
        <xsl:choose>
            <xsl:when test="position() mod 2 = 0">even</xsl:when>
            <xsl:otherwise>odd</xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:choose>
        <xsl:when test="$odd_or_even = 'even'">
            <p style="background-color: yellow">even row:
                <xsl:value-of select="./temperature" />
            </p>
        </xsl:when>
        <xsl:otherwise>
            <p style="background-color: white">odd row:
                <xsl:value-of select="./temperature" />
            </p>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

<?xml version="1.0" encoding="UTF-16"?><p style="background-color: white">odd row:
                76</p><p style="background-color: yellow">even row:
                81</p><p style="background-color: white">odd row:
                72</p>


Determining the Current Node

A node in a node-set becomes the current node as a result of the implicit looping to process all nodes of a certain kind in an <xsl:apply-templates> or <xsl:for-each> element. You can always access the current node, using the current() function. This will be identical to the context node and can be represented in an XPath expression as "." (a single period, which is the abbreviated syntax for self::node()).

The one exception may be when a node is referenced in the predicate of an XPath expression. The context node remains the node currently being processed in the node-set, while the current node temporarily shifts depending on the XPath expression in the predicate.

The two XSLT template rules in the XSLT sample file below recursively walk through the document, displaying the context node, the current node, and the value of all elements in weather.xml.

The formatted output below shows that the context node and the current node are the same all the way through the document.

Example

XML File (weather.xml)

Change the href attribute in weather.xml (shown in Sample XML Data File for XPath Context and Navigation) to reference weathercurrnode.xsl.

XSLT File (weathercurrnode.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="/">
    <table border="1">
        <tr>
            <th>Context</th><th>Current</th><th>Node value</th>
        </tr>
    <xsl:apply-templates/>
    </table>
</xsl:template>
<xsl:template match="*">
    <tr>
        <!-- Display context node's name -->
        <td><xsl:value-of select="name()"/></td>
        <!-- Display current node's name -->
        <td><xsl:value-of select="name(current())"/></td>
        <!-- Display node's value -->
        <td><xsl:value-of select="."/></td>
    </tr>
    <!-- Recurse through ELEMENT children of the current node.
(Without select="*", ALL children are selected. This causes
the text nodes to display in a list apart from the table.) -->
    <xsl:apply-templates select="*"/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

A portion of the processor output is shown here, with line breaks added.

<?xml version="1.0" encoding="UTF-16"?>
<table border="1">
<tr><th>Context</th><th>Current</th><th>Node value</th></tr>
<tr><td>weather</td><td>weather</td><td>  76 67 5     81 30 10 Rain   72 60 2 Fog  </td></tr>
<tr><td>today</td><td>today</td><td> 76 67 5   </td></tr>
...
</table>

See Also

Using Abbreviations in XPath Expressions


Understanding How the Context Node Changes

The context node implicitly changes as the XPath-aware processor works its way through the location steps in a non-important location path.

There is no way to demonstrate this built-in changing of the context node by the processor, because the result of the XPath expression is returned to you as a whole, not as a series of steps. You can simulate the process, by decomposing a complete location path into its parts, and displaying where you are at each point.

Part of the data from the sample file, weather.xml, is shown here:

<weather>
    <today>
        <temperature scale="F">76</temperature>
        <humidity>67</humidity>
        <wind unit="mph">5</wind>
        <!-- No precipitation today -->
        <precip />
    </today>
    <forecast day="+1">
        <temperature scale="F">81</temperature>
        <humidity>30</humidity>
        <wind unit="mph">10</wind>
        <precip>Rain</precip>
    </forecast>
    <forecast day="+2">
        <temperature scale="F">72</temperature>
        <humidity>60</humidity>
        <wind unit="mph">2</wind>
        <precip>Fog</precip>
    </forecast>
</weather>

You can trace the steps through the following location path, using the stylesheet weather.xsl:

/weather/forecast/wind/@unit

Steps in a location path are delimited by the slash character, /.

/
/weather
/weather/forecast
/weather/forecast/wind
/weather/forecast/wind/@unit

The only things you want to see are the results of evaluating each specific one of those steps, one at a time. Emphasizing tight XSLT code is not in this example. Here are the templates from the stylesheet:

Example

The five template rules in this style sheet follow the same general method, aside from formatting the output for readability:

  • Match on the portion of the location path of interest.
  • Display the path itself, the name of the context node, and the value of the context node.
  • Process the template rule specifically established for the next portion of the location path.
Note Using a simple <xsl:apply-templates />, without the select attribute, sometimes causes extraneous text to be displayed in the output. For example, omitting a select attribute in the template rule for the <forecast> element's <xsl:apply-templates/> would also cause the <temperature> and <precipitation> elements to be processed by the default template rules.

XML File (weather.xml)

Use the Sample XML Data File for XPath Context and Navigation and change the href attribute to reference weather.xsl.

XSLT File (weather.xsl)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/TR/REC-html40" >

<xsl:template match="/">
    <p>
        <b>Path: /</b><br />
        Name of context node: <b><xsl:value-of select="name()"/></b>
        Value: <b><xsl:value-of select="."/></b>
    </p>
    <xsl:apply-templates select="weather"/>
</xsl:template>
<xsl:template match="/weather">
    <p>
        <b>Path: /weather</b><br />
        Name of context node: <b><xsl:value-of select="name()"/></b>
        Value: <b><xsl:value-of select="."/></b>
    <xsl:apply-templates select="forecast"/>
    </p>
</xsl:template>
<xsl:template match="/weather/forecast">
    <p>
        <hr width="400" size="1" align="left" />
        <b>Path: /weather/forecast</b><br />
        Name of context node: <b><xsl:value-of select="name()"/></b>
        Value: <b><xsl:value-of select="."/></b>
    </p>
    <xsl:apply-templates select="wind"/>
</xsl:template>
<xsl:template match="/weather/forecast/wind">
    <p>
        <b>Path: /weather/forecast/wind</b><br />
        Name of context node: <b><xsl:value-of select="name()"/></b>
        Value: <b><xsl:value-of select="."/></b>
    </p>
    <xsl:apply-templates select="@unit"/>
</xsl:template>
<xsl:template match="/weather/forecast/wind/@unit">
    <p>
        <b>Path: /weather/forecast/wind/@unit</b><br />
        Name of context node: <b><xsl:value-of select="name()"/></b>
        Value: <b><xsl:value-of select="."/></b>
    </p>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

<?xml version="1.0" encoding="UTF-16"?><p xmlns="http://www.w3.org/TR/REC-html40"><b>Path: /</b><br />
        Name of context node: <b></b>
        Value: <b>  76 67 5     81 30 10 Rain   72 60 2 Fog  </b></p><p xmlns="http://www.w3.org/TR/REC-html40"><b>Path: /weather</b><br />
        Name of context node: <b>weather</b>
        Value: <b>  76 67 5     81 30 10 Rain   72 60 2 Fog  </b><p><hr width="400" size="1" align="left" /><b>Path: /weather/forecast</b><br />
        Name of context node: <b>forecast</b>
...</p></p>


How XSLT Template Rules Depend on Context

XSLT template rules cannot be relied on to "fire" in any particular order, each one is evaluated strictly in terms of the context established at that point. This context is strongly influenced both by the built-in XSLT template rules and by <xsl:apply-templates> elements in template rules for higher-level nodes.

Initial Example

The initial example produces some stray data before the desired "Forecast for (Today...)" headings.

XML File (weather.xml)

Use the Sample XML Data File for XPath Context and Navigation and change the href attribute to reference weather1.xsl.

XSLT File (weather1.xsl)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/TR/REC-html40" >

<xsl:template match="forecast">
    <h2>Forecast for (Today <xsl:value-of select="@day"/>):</h2>
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="temperature">
    <p><b>Temperature:
        <xsl:value-of select="."/>&#x0a;<xsl:value-of select="@scale"/>
    </b></p>
</xsl:template>

<xsl:template match="humidity">
    <p><b>Relative humidity:
        <xsl:value-of select="."/>%
    </b></p>
</xsl:template>

</xsl:stylesheet>

Formatted Output

The preceding style sheet appears to process three types of elements: <forecast>, <temperature>, and <humidity>.

The built-in template rules for XSLT are also in effect—in particular, the built-in rule for the root and all element nodes, which looks like this if coded explicitly:

<xsl:template match="/|*" >
    <xsl:apply-templates />
</xsl:template>

By default, all element content is output to the result tree—not just the content of the three explicitly transformed elements.

Data items are shown before the headingwhen the <forecast> template rule is evaluated, the context in which its match expression is evaluated is the context supplied by the default template rule. This works fine for processing the <forecast> elements in the source document, and the corresponding template rules for the <temperature> and <humidity> children of the <forecast> elements are then invoked by the <xsl:apply-templates/> element.

But the context in the <temperature> and <humidity> templates' match expressions are evaluated is not just the context supplied by the <forecast> elements. There are other <temperature> and <humidity> elements in this document—the children of the <today> element. The <today> element's children are processed by any matching template rules.

Note The <wind> and <precip> elements' contents are passed to the result tree even though our style sheet does not include template rules for them. Again, this is a result of the built-in template rule for the root and element nodes.

You can control the XPath context which matched expressions are evaluated, by manipulating the context in two higher level template rules.

To change this document to display only the desired content from the <forecast> elements' <temperature> and <humidity>use the following step:

  1. Supply a specific template rule for the <today> element, suppressing its contents entirely; and
  2. Supply specific child elements to be processed by the <forecast> element's <xsl:apply-templates> element.

In step #1, add the following template rule to the style sheet:

<xsl:template match="/weather/today" />
Note The empty template portion of this template rule. Nothing at all will be instantiated for the <today> element in the source tree.

In step #2, simply change the <forecast> element's template rule as follows:

<xsl:template match="forecast">
    <h2>Forecast for (Today <xsl:value-of select="@day"/>):</h2>
    <xsl:apply-templates select="temperature|humidity"/>
</xsl:template>

Corrected Example

XML File (weather.xml)

Use the Sample XML Data File for XPath Context and Navigation and change the href attribute to reference weathershort.xsl.

XSLT File (weathershort.xsl)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/TR/REC-html40" >

<xsl:template match="/weather/today" />

<xsl:template match="forecast">
    <h2>Forecast for (Today <xsl:value-of select="@day"/>):</h2>
    <xsl:apply-templates select="temperature|humidity"/>
</xsl:template>

<xsl:template match="temperature">
    <p><b>Temperature:
        <xsl:value-of select="."/>&#x0a;<xsl:value-of select="@scale"/>
    </b></p>
</xsl:template>

<xsl:template match="humidity">
    <p><b>Relative humidity:
        <xsl:value-of select="."/>%
    </b></p>
</xsl:template>

</xsl:stylesheet>

Formatted Output

See Also

For more information, see Constructing an XPath Expression.


Sample XML Data File for XPath Context and Navigation

Topics in this section use the following XML data file. To view this with an XSLT file other than weather.xsl, change the href attribute.

XML File (weather.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="weather.xsl" ?>
<!-- Readings for 2000-11-01 -->
<weather>
    <today>
        <temperature scale="F">76</temperature>
        <humidity>67</humidity>
        <wind unit="mph">5</wind>
        <!-- No precipitation today -->
        <precip />
    </today>
    <forecast day="+1">
        <temperature scale="F">81</temperature>
        <humidity>30</humidity>
        <wind unit="mph">10</wind>
        <precip>Rain</precip>
    </forecast>
    <forecast day="+2">
        <temperature scale="F">72</temperature>
        <humidity>60</humidity>
        <wind unit="mph">2</wind>
        <precip>Fog</precip>
    </forecast>
</weather>


Working with Lists of Items Using XPath

This section covers the following:

  • Placing a List of Items into a Table
  • Creating a Comma-Separated List of Items


Placing a List of Items into a Table

A common transformation is to place a list of items into a grid or table. Given a list of product names, you might want to present them two-across in a table, as follows.

product 1 | product 2
product 3 | product 4

Items must be grouped in pairs into table rows. XSLT currently does not have a built-in mechanism to handle arbitrary grouping. A combination of the <xsl:if> element with the test attribute and the following-sibling axis can be used to approximate this behavior. The following template turns a list of "product" elements into a two-column table.

<TABLE BORDER="1">
  <xsl:for-each select="products/product">
    <xsl:if test="(position() mod 2) = 1">
      <TR>
        <TD><xsl:value-of select="."/></TD>
        <TD><xsl:value-of select="following-sibling::product[position()=1]"/></TD>
      </TR>
    </xsl:if>
  </xsl:for-each>
</TABLE>

Repeat through each product element, but use the <xsl:if> element with the expression "position() mod 2 = 1" to isolate only those products that should start a new row, every other product. The name of this product also is placed in the first cell in the row. Then make another cell and place within it the next child—the one filtered out using the <xsl:if>. The query to select the next element navigates to the parent and obtains a set of following siblings.

Three-column tables can be created by adding another cell to the row to obtain another sibling element, and adjusting the expression to allow only every third element to create a new row. You can extrapolate this mechanism to create tables with even more columns.

<TABLE BORDER="1">
  <xsl:for-each select="products/product">
    <xsl:if test="(position() mod 3) = 1">
      <TR>
        <TD><xsl:value-of select="."/></TD>
        <TD><xsl:value-of select="following-sibling::product[position()=1]"/></TD>
        <TD><xsl:value-of select="following-sibling::product[position()=2]"/></TD>
      </TR>
    </xsl:if>
  </xsl:for-each>
</TABLE>

Example

This example demonstrates the table code snippets that are shown above.

XML File (product-list.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="product-list.xsl"?>
<products>
   <product>ActiMates Arthur</product>
   <product>ActiMates Barney</product>
   <product>ActiMates DW</product>
   <product>ActiMates PC Pack</product>
   <product>ActiMates TV Pack</product>
   <product>Arthur's Brainteasers</product>
   <product>Arthur's Math Carnival</product>
   <product>Arthur's Reading Roundup</product>
   <product>Barney fun on the Farm</product>
   <product>Barney goes to the Circus</product>
   <product>Barney under the Sea</product>
</products>

XSLT File (product-list.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <HTML>
    <BODY STYLE="font:bold 10pt Arial">
      <DIV>Two column table:</DIV>

      <TABLE BORDER="1">
        <xsl:for-each select="products/product">
          <xsl:if test="(position() mod 2) = 1">
            <TR>
              <TD><xsl:value-of select="."/></TD>
              <TD><xsl:value-of select="following-sibling::product[position()=1]"/></TD>
            </TR>
          </xsl:if>
        </xsl:for-each>
      </TABLE>
      <BR/>

      <DIV>Three column table:</DIV>
      <TABLE BORDER="1">
        <xsl:for-each select="products/product">
          <xsl:if test="(position() mod 3) = 1">
            <TR>
              <TD><xsl:value-of select="."/></TD>
              <TD><xsl:value-of select="following-sibling::product[position()=1]"/></TD>
              <TD><xsl:value-of select="following-sibling::product[position()=2]"/></TD>
            </TR>
          </xsl:if>
        </xsl:for-each>
      </TABLE>

    </BODY>
  </HTML>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

A portion of the output stream is shown here.

<HTML>
<BODY STYLE="font:bold 10pt Arial">
<DIV>Two column table:</DIV>
<TABLE BORDER="1">
<TR>
<TD>ActiMates Arthur</TD>
<TD>ActiMates Barney</TD>
</TR>
<TR>
<TD>ActiMates DW</TD>
<TD>ActiMates PC Pack</TD>
</TR>
...
</TABLE><BR><DIV>Three column table:</DIV>
<TABLE BORDER="1">
<TR>
<TD>ActiMates Arthur</TD>
<TD>ActiMates Barney</TD>
<TD>ActiMates DW</TD>
</TR>
<TR>
<TD>ActiMates PC Pack</TD>
...
</TR>
</TABLE>
</BODY>
</HTML>


Creating a Comma-Separated List of Items

The last() function can be used to determine if the element is the last one in the query.

<DIV>
  <xsl:for-each select="products/product">
    <xsl:value-of select="."/> <xsl:if test="position()!=last()">, </xsl:if>
    </xsl:for-each>
</DIV>

Because the comma is being inserted based on the position in the query and not the source document, the list can be sorted without creating errors in the results. The following template shows how to add commas to a sorted product list.

<DIV>
  <xsl:for-each select="products/product">
    <xsl:sort select="product" order="descending"/>
      <xsl:value-of select="."/><xsl:if test="position()!=last()">, </xsl:if>
  </xsl:for-each>
</DIV>

The <xsl:sort> order attribute is given the value "descending" to indicate a descending sort by product name. The preceding two code snippets are shown in the following example.

You can separate the comma logic from outputting the element value. In the following template rule, the names in a group of names are formatted as a comma-separated list.

<xsl:template match="namelist/name">
  <xsl:apply-templates/>
  <xsl:if test="position()!=last()">, </xsl:if>
</xsl:template>

Another way to separate the comma and node printing is by reversing the logic to verify whether this name is the first. In some cases, this performs better than the preceding example because last() requires that the entire set of names be found and counted, while this one does not.

<xsl:template match="namelist/name">
  <xsl:if test="position()!=1">, </xsl:if>
  <xsl:apply-templates/>
</xsl:template>

The preceding two snippets are used with another template rule to display the name value itself:

<xsl:template match="name">
   <xsl:value-of select=".">
</xsl:template>

Example

XML File (product-list2.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="product-list2.xsl"?>
<products>
   <product>ActiMates Arthur</product>
   <product>ActiMates Barney</product>
   <product>ActiMates DW</product>
   <product>ActiMates PC Pack</product>
   <product>ActiMates TV Pack</product>
   <product>Arthur's Brainteasers</product>
   <product>Arthur's Math Carnival</product>
   <product>Arthur's Reading Roundup</product>
   <product>Barney fun on the Farm</product>
   <product>Barney goes to the Circus</product>
   <product>Barney under the Sea</product>
</products>

XSLT File (product-list2.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <HTML>
    <BODY STYLE="font:10pt Arial">
      <DIV><B>Comma separated list:</B></DIV>
      <DIV>
        <xsl:for-each select="products/product">
          <xsl:value-of select="."/> <xsl:if test="position()!=last()">, </xsl:if>
          </xsl:for-each>
      </DIV>
      <BR/>

      <DIV><B>Comma separated and reverse-sorted list:</B></DIV>
      <DIV>
        <xsl:for-each select="products/product">
          <xsl:sort select="product" order="descending"/>
            <xsl:value-of select="."/><xsl:if test="position()!=last()">, </xsl:if>
        </xsl:for-each>
      </DIV>
    </BODY>
  </HTML>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Comma separated list:

ActiMates Arthur, ActiMates Barney, ActiMates DW, ActiMates PC Pack, ActiMates TV Pack, Arthur's Brainteasers, Arthur's Math Carnival, Arthur's Reading Roundup, Barney fun on the Farm, Barney goes to the Circus, Barney under the Sea

Comma separated and reverse-sorted list:

Barney under the Sea, Barney goes to the Circus, Barney fun on the Farm, Arthur's Reading Roundup, Arthur's Math Carnival, Arthur's Brainteasers, ActiMates TV Pack, ActiMates PC Pack, ActiMates DW, ActiMates Barney, ActiMates Arthur

Processor Output

<HTML>
<BODY STYLE="font:10pt Arial">
<DIV><B>Comma separated list:</B></DIV>
<DIV>ActiMates Arthur, ActiMates Barney, ..., Barney under the Sea</DIV><BR><DIV><B>Comma separated and reverse-sorted list:</B></DIV>
<DIV>Barney under the Sea, Barney goes to the Circus, ..., ActiMates Arthur</DIV>
</BODY>
</HTML>


Using XPath Axes to Navigate through XML Data

An axis in XPath is similar to an axis in a traditional two or three dimensional chart or graph. It tells the XPath-aware processor which direction to look, up, down, or sideways in a document tree, starting from a given point of origin—the context node. Using an axis as part of a location step is:

axisname::nodetest

Where axisname is one of the built-in axes defined by the XPath specification, selected from the list below, and nodetest indicates which node(s) along that axis are of interest. For example:

child::*

indicates to select all children of the context node, while

/child::*

is to select all children of the root node, which is made the context node by virtue of the opening slash.

Using an axis in an XPath expression extends your options in navigating through the document tree. A traditional unidirectional path, such as to a file on a Web server, is similar to the following:

/rootfolder/subfolder/subsubfolder

unlike this sort of path or a traditional charting application with its X, Y, and Z axes, XPath provides you with a rich variety of axes. Each XPath axis consist of a tree-like structure to the context node.

The following topics describe each XPath navigation axis. Each topic presents an Extensible Stylesheet Language Transformation (XSLT) file that works with the Sample XML File for Navigating XPath Axes. The XSLT template rules are also presented as a long file, Sample XSLT File for Navigating XPath Axes.

  • Navigating Along the child Axis
  • Navigating Along the descendant Axis
  • Navigating Along the parent Axis
  • Navigating Along the ancestor Axis
  • Navigating Along the following Axis
  • Navigating Along the preceding Axis
  • Navigating Along the following-sibling Axis
  • Navigating Along the preceding-sibling Axis
  • Navigating Along the attribute Axis
  • Navigating Along the namespace Axis
  • Navigating Along the self Axis
  • Navigating Along the descendant-or-self Axis
  • Navigating Along the ancestor-or-self Axis
  • Using Abbreviations in XPath Expressions

See Also

Constructing the Node-Test Portion of a Location Step | Determining the Context Node


Navigating Along the child Axis

The child axis selects nodes that are immediate children of the context node. For example, if the context node is the root <chairman> element:

child::president

locates a node set consisting of two <president> elements:

  • <president empID="emp4390" empdate="1980-06-18">, and
  • <president empID="emp4238" empdate="1984-08-12">

Assuming the same context node, changing the location step to:

child::president | child::name

will locate a node-set consisting of the above two elements and the <name>Amy Egert</name> element.

Only the root node and element nodes in a document have nodes along the child:: axis. This means that, comments, attributes, processing instructions (PIs), and namespaces do not have children. Similarly, only element nodes may be located along the child:: axis if you use a name node test, such as a specific element name, or * for all elements. If you need to select comments and PIs as well, use the node() or other node-type test. For example:

child::node()

locates all comments and PIs which are children of the context node, as well as all element children, while:

child::comment()

locates all comments which are children of the context node, while excluding all PI and element nodes.

The child:: axis is the default, if no axis is supplied in a location step. Therefore, the following are equivalent:

child::name
name

See Also

Sample XML File for Navigating XPath Axes | Constructing the Node-Test Portion of a Location Step


Navigating Along the descendant Axis

The descendant:: axis of a given context node locates all element nodes which the context node contains, that is, all children, all the children's children, and so on. The location step:

/descendant::*

locates all elements descended from the root node, and therefore locates all elements in a given document.

Since the descendant:: axis extends the child:: axis recursively through the context node's tree, the same restrictions apply as for the child:: axis. In particular, using a name node test, specific element names or the * for all elements, do not select comments and PIs descended from the context node. If you need to select comments and PIs as well as elements, use:

descendant::node()

attributes and namespaces can never be located on the child:: axis, and therefore cannot be located on the descendant:: axis.

See Also

Sample XML File for Navigating XPath Axes | Navigating Along the child Axis


Navigating Along the parent Axis

The parent:: axis is the inverse of the child:: axis. It selects the node in the document tree that is immediately above the context node, in hierarchical order.

All nodes except the root node have one and only one parent node; the root node has no parent. The parent of a namespace or attribute node is the element node declaring it. The parent of a comment or PI is the element that contains it, or, if the comment or PI precedes or follows the root element, the parent is the root node.

In the XSLT template rule shown below, the match pattern for the template rule sets the context node to a particular <director> element, the one whose <name> element equals "Michelle Votava". The template portion of the rule builds a table with several rows: one for column headings, and one for each attribute of the requested <director> element. For each such attribute, the template constructs a table cell for the name of the attribute, its value, and using the parent:: axis, the name and value of the attribute's parent.

Example

XML File (orgchart.xml)

Use orgchart.xml (in Sample XML File for Navigating XPath Axes) and edit its href attribute to refer to orgchart-parent.xsl.

XSLT File (orgchart-parent.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- suppress text nodes not covered in subsequent template rule: -->
<xsl:template match="text()"/>

<xsl:template match="director[name='Michelle Votava']">
    <table border="1">
        <tr>
            <th>Attribute name</th>
            <th>Attribute value</th>
            <th>Parent name</th>
            <th>Parent value</th>
        </tr>
            <xsl:for-each select="attribute::*">
                <tr>
                  <td><xsl:value-of select="name()"/></td>
                  <td><xsl:value-of select="."/></td>
                  <td><xsl:value-of select="name(parent::*)"/></td>
                  <td><xsl:value-of select="parent::*"/></td>
                </tr>
            </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Note The parent of an attribute is considered to be the element in whose start tag the attribute is assigned a value.

See Also

Navigating Along the child Axis


Navigating Along the ancestor Axis

The ancestor:: axis locates all nodes in the document hierarchy above the context node. It locates the parent of the context node, the parent's parent, and so on up to the root node. The root node is an ancestor of all other nodes in the document, and itself has no ancestors.

Since ancestor:: extends the parent:: axis all the way back through the document tree, all limitations and effects of the parent:: axis apply to the ancestor:: axis as well.

If you wanted to show the names of all employees along the ancestor axis of the employee whose name is Peter Porzuczek that is, all of Peter Porzuczek's supervisors, you could use the sample XSLT template rule below.

The ancestors are retrieved in document order. That is, the ancestor furthest up the tree is displayed first, followed by its child, followed by the child's child.

Example

XML File (orgchart.xml)

Use orgchart.xml (in Sample XML File for Navigating XPath Axes) and edit its href attribute to refer to orgchart-ancestor.xsl.

XSLT File (orgchart-ancestor.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="*[name='Peter Porzuczek']">
    <h2>Peter Porzuczek's superiors:</h2>
        <xsl:for-each select="ancestor::*">
            <h4><xsl:value-of select="name"/></h4>
        </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Formatted Output

See Also

Navigating Along the parent Axis


Navigating Along the following Axis

All nodes that follow the context node, in document order, lie along the following:: axis. This specifically excludes attribute and namespace nodes, as well as nodes that are descendants of the context node.

Given the sample XML document of Lucerne Publishing's organization chart, you could locate, all employees that follow the employee named Katie McAskill-White with the XSLT template rule shown below.

Because the context node established by the template rule's match pattern is the <name> element whose string value is Katie McAskill-White (match="name[.='Katie McAskill-White']"), the <xsl:for-each> element's select pattern, "following::*/name," locates the names of all employees that follow the context node, in document order.

Example

XML File (orgchart.xml)

Use orgchart.xml (in Sample XML File for Navigating XPath Axes) and edit its href attribute to refer to orgchart-follow.xsl.

XSLT File (orgchart-follow.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="name[.='Katie McAskill-White']">
    <h2>Katie McAskill-White's followers:</h2>
        <xsl:for-each select="following::*/name">
            <h4><xsl:value-of select="."/></h4>
        </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Formatted Output


Navigating Along the preceding Axis

The preceding:: axis is the inverse of the following:: axis. It locates all nodes that come before the context node in document order. Ancestors, attribute nodes, and namespace nodes cannot be located along the context node's preceding:: axis.

In the sample organization chart document, if the context node is the <name> element containing "John Tippett," you can locate and display all preceding element nodes using the template rule shown below. This template rule creates a table in the result tree. Aside from the table headings, each row consists of the name of a preceding node, and that node's value. If the node name is "name", the row is colored yellow, otherwise white.

Example

XML File (orgchart.xml)

Use orgchart.xml (in Sample XML File for Navigating XPath Axes) and edit its href attribute to refer to orgchart-prec.xsl.

XSLT File (orgchart-prec.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="name[.='John Tippett']">
    <table border="1">
        <tr>
            <th>Node name</th>
            <th>Node value</th>
        </tr>
            <xsl:for-each select="preceding::*">
            <xsl:variable name="bgcolor">
                    <xsl:choose>
                        <xsl:when test="name()='name'">yellow</xsl:when>
                        <xsl:otherwise>white</xsl:otherwise>
                    </xsl:choose>
            </xsl:variable>
                <tr>
                    <xsl:attribute name="style">background-color: <xsl:value-of select="$bgcolor"/>
                    </xsl:attribute>
                    <td>
                        <xsl:value-of select="name()"/>
                    </td>
                    <td>
                        <xsl:value-of select="."/>
                    </td>
                </tr>
            </xsl:for-each>
        </table>
</xsl:template>

</xsl:stylesheet>

Formatted Output

See Also

Navigating Along the following Axis


Navigating Along the following-sibling Axis

The following-sibling:: XPath axis locates all nodes, elements only, by default which share the same parent as the context node itself, and which appear in their entirety after the context node, in document order. Since the root node has no parent, it also has no following-siblings. If the context node is an attribute or namespace node, the following-sibling:: node locates an empty node-set.

In the sample XML document, each <name> element is followed in the document tree by information about the given employee's organization, including employees at the same level of the hierarchy. This information can be captured by the XSLT template rule for the employee named Shelly Szymanski, shown in the sample XSLT file.

The template rule in the sample XSLT file contains two references to the following-sibling:: axis. The first, used as the value of the <xsl:if> element's test attribute, ensures that the template will be created in the result tree only if the selected <name> element has following-sibling nodes.

This example also demonstrates that the string-value of an element node is a combination of all text nodes contained by that element. In our sample document, the <director> elements do not contain any text nodes of their own. The only text nodes belong to the <name> and <region> elements subordinate to a given <director> element. Thus, the string-value of each <director> element is the combined string-value of all subordinate <name> and <region> elements.

Example

XML File (orgchart.xml)

Use orgchart.xml (in Sample XML File for Navigating XPath Axes) and edit its href attribute to refer to orgchart-followsib.xsl.

XSLT File (orgchart-followsib.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="name[.='Shelly Szymanski']">
    <xsl:if test="following-sibling::*">
        <h2>following-siblings of &lt;name&gt;
            '<xsl:value-of select="."/>'</h2>
        <table border="1">
            <tr>
                <th>Node name</th>
                <th>Node value</th>
            </tr>
                <xsl:for-each select="following-sibling::*">
                    <tr>
                        <td><xsl:value-of select="name()"/></td>
                        <td><xsl:value-of select="."/></td>
                    </tr>
                </xsl:for-each>
            </table>
        </xsl:if>
</xsl:template>

</xsl:stylesheet>

Formatted Output


Navigating Along the preceding-sibling Axis

Similar to the following-sibling:: axis, the preceding-sibling:: axis locates all nodes, elements, by default, which share the same parent node and which appear before the context node, in document order. Since the root node has no parent, it also has no preceding-siblings. If the context node is an attribute or namespace node, the preceding-sibling:: node locates an empty node-set.

You can override the default elements only selection of preceding-siblings by using the node() node test in the location step. For example, you can locate all of the root <chairman> element's preceding-sibling nodes of type element, node, or processing instruction (PI) using an XSLT template such as the one in the sample XSLT file.

The template rule in the sample XSLT file contains two references to the preceding-sibling:: axis. The first appears as the value of the <xsl:if> element's test attribute. It ensures that the template is instantiated in the result tree only if the context node has at least one node along the preceding-sibling:: axis.

Example

XML File (orgchart.xml)

Use orgchart.xml (in Sample XML File for Navigating XPath Axes) and edit its href attribute to refer to orgchart-presibl.xsl.

XSLT File (orgchart-presibl.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="chairman">
    <xsl:if test="preceding-sibling::node()">
        <h2>preceding-siblings of '<xsl:value-of select="name"/>'</h2>
    <table border="1">
            <tr>
                <th>Node name</th>
                <th>Node value</th>
        </tr>
        <xsl:for-each select="preceding-sibling::node()">
            <tr>
               <td><xsl:value-of select="name()"/></td>
                <td><xsl:value-of select="."/></td>
            </tr>
        </xsl:for-each>
        </table>
   </xsl:if>
   <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Since the root element, by definition, has no siblings, the only node located along its preceding-sibling:: axis in this case is the <?xml-stylesheet?> processing instruction.

See Also

Navigating Along the following-sibling Axis


Navigating Along the attribute Axis

When the context node is an element, use the attribute:: axis to locate that element's attributes. The attribute:: axis can be used only with element-type context nodes, and it locates attributes only.

To display a table of all employees' IDs and dates of employment, you could use three XSLT template rules, one that employs the attribute:: axis. This is shown in the XSLT sample file below.

The first template rule sets up the body of the result tree, including a table and a row of table headers. The second template rule suppresses the output of all element and text nodes, note the empty <xsl:template> element.

The third template rule makes an exception for the second, which is to process all <name> elements. The template placed into the result tree by this rule consists of a table row with four cells:

  • The value of this <name> element
  • The value of the parent element's empID attribute
  • The value of the parent element's empdate attribute

Example

XML File (orgchart.xml)

Use orgchart.xml (in Sample XML File for Navigating XPath Axes) and edit its href attribute to refer to orgchart-attr.xsl.

XSLT File (orgchart-attr.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="/">
    <html>
        <head><title>Employee Info</title></head>
             <body>
              <table border="1">
                <tr>
                    <th>Name</th>
                    <th>Emp ID</th>
                    <th>Empl Date</th>
                </tr>
                <xsl:apply-templates />
            </table>
             </body>
    </html>
</xsl:template>

<xsl:template match="*/text()"/>

<xsl:template match="name">
    <tr>
        <td><xsl:value-of select="."/></td>
        <td><xsl:value-of select="parent::*/attribute::empID"/></td>
        <td><xsl:value-of select="parent::*/attribute::empdate"/></td>
    </tr>
</xsl:template>

</xsl:stylesheet>

Formatted Output


Navigating Along the namespace Axis

When the context node is an element, the namespace:: axis will locate all namespace nodes which apply to that element. The namespace:: axis can be used only with elements, and locates only namespace nodes.

A typical XSLT style sheet for use with Microsoft Internet Explorer declares two namespaces: one for elements in the XSLT namespace itself, and one for elements in the HTML 4.0 namespace. Although our sample orgchart.xml document contains no namespace declarations, the following XSLT style sheet, namespace.xsl, can be used with any source XML document which does contain them.

Note The <?xml-stylesheet?> processing instruction refers to this style sheet itself. Therefore you can even open this style sheet directly in Internet Explorer.

The namespace.xsl style sheet contains three template rules:

  • The template rule <xsl:template match="/"> sets up basic HTML elements in the result tree.
  • The template rule <xsl:template match="text()"/> suppresses all text nodes.
  • The template rule <xsl:template match="*"> matches all element nodes. For each element:
    • A heading is instantiated in the result tree, Namespaces in effect for <elementname> element:.
    • A table is created consisting of two rows. Row 1 is the table column headings: Local name, Namespace URI, and Namespace node(s). Row 2 shows, the value of the local-name() function for the context node; the value of the namespace-uri() function for the context node; and the value(s) of any namespace node(s) in scope for the context node, each on a separate line.

Example

Regardless of the namespace URI, which applies to a given element name (shown in the second column), each element has a namespace node (third column, the nodes along the namespace:: axis) for every namespace that it or any of its ancestors declares.

XML File (nsdemo.xml)

<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="namespace.xsl" ?>
<nsdemo
    xmlns:ns="http://uri.for.ns-prefix"
    xmlns="http://uri.for.no-prefix">
    <branch1>
        <ns:sub_branch1.1/>
        <sub_branch1.2/>
    </branch1>
    <branch2 xmlns:ns2="http://uri.for.ns2-prefix">
        <ns:sub_branch2.1/>
        <sub_branch2.2/>
        <ns2:sub_branch2.3/>
    </branch2>
</nsdemo>

XSLT File (namespace.xsl)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="namespace.xsl" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/TR/REC-html40" >

    <xsl:template match="/">
        <html>
            <head><title>Namespaces in XSLT Style Sheet</title></head>
            <body>
                <xsl:apply-templates />
            </body>
            </html>
    </xsl:template>

    <xsl:template match="text()"/>

    <xsl:template match="*">
        <h3>Namespaces in effect for &lt;<xsl:value-of select="name()"/>&gt; element:</h3>
        <table border="1">
            <tr>
                <th>Local-name</th>
                <th>Namespace-uri</th>
                <th>Namespace node(s)</th>
            </tr>
            <tr>
                <td valign="top"><xsl:value-of select="local-name()"/></td>
                <td valign="top"><xsl:value-of select="namespace-uri()"/></td>
                <td valign="top">
                    <xsl:for-each select="namespace::*">
                        <xsl:value-of select="."/><br />
                    </xsl:for-each>
                </td>
            </tr>
        </table>
          <xsl:apply-templates/>
    </xsl:template>

</xsl:stylesheet>

Formatted Output

See Also

Sample XML File for Navigating XPath Axes


Navigating Along the self Axis

The self:: axis always locates the context node. It is often used to retrieve the value of the current node, particularly as the select attribute of the <xsl:value-of> element.

To display the name of each employee in the international division identified in the sample XML document as a level-2 heading, you could use a simple XSL template rule such as the XSLT file shown below.

Example

XML File (orgchart.xml)

Use orgchart.xml (in Sample XML File for Navigating XPath Axes) and edit its href attribute to refer to orgchart-self.xsl.

XSLT File (orgchart-self.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="president[division='International']">
    <xsl:for-each select="descendant::name">
        <h2><xsl:value-of select="self::*"/></h2>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Katie McAskill-White

Neil Charney

Beth Silverberg

Lani Ota

Peter Porzuczek

Marea Angela Castaneda


Navigating Along the descendant-or-self Axis

The descendant-or-self:: axis, like the descendant:: axis, locates all nodes which are descended from the context node, its children, its children's children, and so on. Unlike descendant::, however, descendant-or-self:: also selects the context node itself.

Attribute and namespace nodes cannot be located using the descendant-or-self:: axis. Since attribute and namespace nodes have no descendants, using descendant-or-self:: when the context node is an attribute or namespace node always returns an empty node-set. To locate descendant comment and processing instruction (PI) nodes as well as elements, use the node(), comment(), or processing-instruction() node-type test with this axis.

To display information about the employee named Steve Masters and the employees whose elements descend from his in orgchart.xml, you can use an XSLT template rule such as orgchart-descself.xsl, below.

Once the template rule's match pattern ("name[.='Steve Masters']") has established the branch of the family tree to be processed, the template rule sets up a level-2 heading and a table for each <name> element node along the descendant-or-self:: axis. Each row of the table, other than column headers, contains the value of that <name> element, and the value of its parent's empID and empdate attributes.

Example

XML File (orgchart.xml)

Use orgchart.xml (in Sample XML File for Navigating XPath Axes) and edit its href attribute to refer to orgchart-descself.xsl.

XSLT File (orgchart-descself.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="name[.='Steve Masters']">
    <h2>Steve Masters and descendant elements:</h2>
    <table border="1">
        <tr>
            <th>Name</th>
            <th>Emp ID</th>
            <th>Empl Date</th>
        </tr>
        <xsl:for-each select="parent::*/descendant-or-self::name">
            <tr>
                <td><xsl:value-of select="."/></td>
                <td><xsl:value-of select="parent::*/@empID"/></td>
                <td><xsl:value-of select="parent::*/@empdate"/></td>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Note Amy Egert (Steve Masters's "parent") and Katie McAskill-White (Masters's "sibling") do not appear in the list, as neither of those relationships are ever found on the descendant-or-self:: axis.

See Also

Navigating Along the descendant Axis


Navigating Along the ancestor-or-self Axis

The ancestor-or-self:: axis, like the ancestor:: axis, locates all nodes in the document hierarchy above the context node. It locates the parent of the context node, the parent's parent, and so on up to the root node. Unlike ancestor::, however, ancestor-or-self:: also selects the context node itself.

Attribute and namespace nodes cannot be located along the ancestor-or-self:: axis, unless the context node is itself an attribute or namespace node. In the latter case, the context node is located because of the "or-self" component of this axis.

Again referring to our sample XML document, who is in the "chain of command" responsible for setting Josh Barnhill's goals and objectives? You can answer this question with a template rule such as the XSLT file shown below.

The position() and last() functions are used to calculate the number of steps above "Josh Barnhill". For more information, see Using Functions in XPath Expressions.

Example

XML File (orgchart.xml)

Use orgchart.xml (in Sample XML File for Navigating XPath Axes) and edit its href attribute to refer to orgchart-ancself.xsl.

XSLT File (orgchart-ancself.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="name[.='Josh Barnhill']">
    <h2>Josh Barnhill's reporting structure:</h2>
    <table border="1">
        <tr>
            <th>Generation</th>
            <th>Name</th>
            <th>Emp ID</th>
            <th>Empl Date</th>
        </tr>
        <xsl:for-each select="ancestor-or-self::*[name()!='name']">
            <tr>
                <td align="center">
                    <xsl:value-of select="position()-last()"/>
                </td>
                <td><xsl:value-of select="name"/></td>
                <td><xsl:value-of select="@empID"/></td>
                <td><xsl:value-of select="@empdate"/></td>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

Formatted Output

See Also

Navigating Along the ancestor Axis


Using Abbreviations in XPath Expressions

Several shortcuts are available to be used in place of certain axes:

  • The default axis if none is provided in a given location step is child::. Therefore, the following two location steps are equivalent, both locate a <name> child of the context node:
    child::name
name
  • The "at sign," @, is a shortcut for the attribute:: axis. Therefore, the following two location steps are equivalent, both locate the empdate attribute of a <director> child of the context node:
    director/attribute::empdate
ddirector/@empdate
  • Two succeeding slashes, //, is a shortcut for /descendant-or-self::node()/.Therefore, the following two location steps are equivalent, locating both the node whose name is "name" and whose string-value is "Amy Egert," and all its descendants, except attribute and namespace nodes:
    name[.="Amy Egert"]/descendant-or-self::node()/name
name[.="Amy Egert"]//name
  • A single period, ., is a shortcut for self::node(). Therefore, the following two location steps, which locate an attribute of the context node, are equivalent:
    self::node()/attribute::empdate
./attribute::empdate

    This XPath location step can be further abbreviated using the shortcut for the attribute:: axis, for example:

    ./@empdate
  • Two succeeding periods, , are a shortcut for parent::node(). Therefore, the following two location steps are equivalent, both select the parent of the context node, when the parent's value is "Josh Barnett":
    parent::node()[self::node()="Josh Barnett"]
..[self::node()="Josh Barnett"]

    This location step could be abbreviated even further, using the shortcut for self::node(), as follows:

    ..[.="Josh Barnett"]
  • The asterisk is a wild-card character, used in a name node test to indicate that selected nodes may have any names at all. Therefore, given that various elements in orgchart.xml have the same two attributes, empID and empdate, the following two location steps are equivalent, assuming the context node to be one of these elements:
    attribute::empID | attribute::empdate
attribute::*

    This location step could be abbreviated even further, using the shortcut for the attribute:: axis, as follows:

    @*
  • While not really a shortcut, a single leading slash, representing the document root in an XPath expression always makes it an absolute path, relative to the document root. Therefore, the following location steps are not equivalent:
    name
/name

The first selects all <name> elements which are children of the context node; the second, all <name> elements which are children of the root node, that is, it selects an empty node-set, since the root node's only child is the <chairman> element).

Example

This example doesn't generate significant output. It demonstrates that no errors are generated by the above XPath expressions.

XML File (booksxpath.xml)

Use the orgchart.xml (in Sample XML File for Navigating XPath Axes) and change its href attribute to point to xpabbr.xsl.

XSLT File (xpabbr.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="president">
   <p/>child::name --
      <xsl:value-of select='child::name'/>
   <p/>name --
      <xsl:value-of select='name'/>
   <p/>director/attribute::empdate --
      <xsl:value-of select='director/attribute::empdate'/>
   <p/>ddirector/@empdate --
      <xsl:value-of select='ddirector/@empdate'/>
   <p/>name[.="Amy Egert"]/descendant-or-self::node()/name --
      <xsl:value-of select='name[.="Amy Egert"]/descendant-or-self::node()/name'/>
   <p/>name[.="Amy Egert"]//name --
      <xsl:value-of select='name[.="Amy Egert"]//name'/>
   <p/>self::node()/attribute::empdate --
      <xsl:value-of select='self::node()/attribute::empdate'/>
   <p/>./attribute::empdate --
      <xsl:value-of select='./attribute::empdate'/>
   <p/>./@empdate --
      <xsl:value-of select='./@empdate'/>
   <p/>parent::node()[self::node()="Josh Barnett"] --
      <xsl:value-of select='parent::node()[self::node()="Josh Barnett"]'/>
   <p/>..[self::node()="Josh Barnett"] --
      <xsl:value-of select='..[self::node()="Josh Barnett"]'/>
   <p/>..[.="Josh Barnett"] --
      <xsl:value-of select='..[.="Josh Barnett"]'/>
   <p/>attribute::empID | attribute::empdate --
      <xsl:value-of select='attribute::empID | attribute::empdate'/>
   <p/>attribute::* --
      <xsl:value-of select='attribute::*'/>
   <p/>@* --
      <xsl:value-of select='@*'/>
   <p/>name --
      <xsl:value-of select='name'/>
   <p/>/name --
      <xsl:value-of select='/name'/>
</xsl:template>

</xsl:stylesheet>

See Also

Sample XML File for Navigating XPath Axes


Sample XML File for Navigating XPath Axes

An XML file is structured as a hierarchical tree. This tree structuring matches the structure of family trees and organization charts.

For example, a portion of Lucerne Publishing's corporate structure might be represented by the following XML document.

To use this XML file to test the various XSLT files that contain axis templates later in this section, modify the href attribute here to reference the correct XSLT file.

XML File (orgchart.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="orgchart.xsl"?>
<chairman empID="emp3456" empdate="1976-03-21">
    <name>Amy Egert</name>
    <president empID="emp4390" empdate="1980-06-18">
        <name>Steve Masters</name>
        <division>Domestic</division>
        <groupvp empID="emp9801" empdate="1981-09-01">
            <name>Shelly Szymanski</name>
            <department>Sales</department>
            <director empID="emp5443" empdate="1993-04-19">
                <name>Cindy Durkin</name>
                <region>Northeast</region>
            </director>
            <director empID="emp2348" empdate="1990-06-02">
                <name>Michelle Votava</name>
                <region>Southeast</region>
            </director>
            <director empID="emp4322" empdate="1995-05-26">
                <name>John Tippett</name>
                <region>Southwest</region>
            </director>
            <director empID="emp4587" empdate="1990-12-20">
                <name>Alan Steiner</name>
                <region>Northwest</region>
            </director>
        </groupvp>
        <groupvp empID="emp4320" empdate="1978-11-09">
            <name>John Thorson</name>
            <department>Marketing</department>
        </groupvp>
        <groupvp empID="emp3961" empdate="1990-01-01">
            <name>Josh Barnhill</name>
            <department>Production</department>
        </groupvp>
    </president>
    <president empID="emp4238" empdate="1984-08-12">
        <name>Katie McAskill-White</name>
        <division>International</division>
        <groupvp empID="emp7216" empdate="1987-04-13">
            <name>Neil Charney</name>
            <department>Sales</department>
            <director empID="emp9032" empdate="1982-08-31">
                <name>Beth Silverberg</name>
                <region>Africa</region>
            </director>
            <director empID="emp7634" empdate="1994-02-12">
                <name>Lani Ota</name>
                <region>Asia</region>
            </director>
            <director empID="emp9032" empdate="1991-10-03">
                <name>Peter Porzuczek</name>
                <region>Europe</region>
            </director>
        </groupvp>
        <groupvp empID="emp3833" empdate="1991-05-15">
            <name>Marea Angela Castaneda</name>
            <department>Marketing</department>
        </groupvp>
    </president>
</chairman>


Sample XSLT File for Navigating XPath Axes

A subset of this file is used in each topic for XPath navigation axes.

XSLT File (orgchart.xsl)

<?xml version="1.0"?>
<xsl:stylesheet
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   version="1.0">

<!-- Common template rule (suppresses all text nodes not
   explicitly covered in succeeding template rules) -->
<xsl:template match="text()"/>

<!-- Parent axis -->
<xsl:template match="director[name='Michelle Votava']">
   <table border="1">
      <tr>
         <th>Attribute name</th>
         <th>Attribute value</th>
         <th>Parent name</th>
         <th>Parent value</th>
      </tr>
          <xsl:for-each select="attribute::*">
             <tr>
               <td><xsl:value-of select="name()"/></td>
               <td><xsl:value-of select="."/></td>
               <td><xsl:value-of select="name(parent::*)"/></td>
               <td><xsl:value-of select="parent::*"/></td>
             </tr>
          </xsl:for-each>
   </table>
</xsl:template>

<!-- Ancestor axis -->
<xsl:template match="*[name='Peter Porzuczek']">
   <h2>Peter Porzuczek's superiors:</h2>
       <xsl:for-each select="ancestor::*">
          <h4><xsl:value-of select="name"/></h4>
       </xsl:for-each>
</xsl:template>

<!-- Following axis -->
<xsl:template match="name[.='Katie McAskill-White']">
   <h2>Katie McAskill-White's followers:</h2>
       <xsl:for-each select="following::*/name">
          <h4><xsl:value-of select="."/></h4>
       </xsl:for-each>
</xsl:template>

<!-- Preceding axis -->
<xsl:template match="name[.='John Tippett']">
   <table border="1">
      <tr>
         <th>Node name</th>
         <th>Node value</th>
      </tr>
          <xsl:for-each select="preceding::*">
         <xsl:variable name="bgcolor">
                <xsl:choose>
                   <xsl:when test="name()='name'">yellow</xsl:when>
                   <xsl:otherwise>white</xsl:otherwise>
                </xsl:choose>
         </xsl:variable>
             <tr>
                <xsl:attribute name="style">background-color: <xsl:value-of select="$bgcolor"/>
                </xsl:attribute>
                <td>
                   <xsl:value-of select="name()"/>
                </td>
                <td>
                   <xsl:value-of select="."/>
                </td>
             </tr>
          </xsl:for-each>
       </table>
</xsl:template>

<!-- Following-sibling axis -->
<xsl:template match="name[.='Shelly Szymanski']">
   <xsl:if test="following-sibling::*">
      <h2>following-siblings of &lt;name&gt;
         '<xsl:value-of select="."/>'</h2>
      <table border="1">
         <tr>
            <th>Node name</th>
            <th>Node value</th>
         </tr>
             <xsl:for-each select="following-sibling::*">
                <tr>
                   <td><xsl:value-of select="name()"/></td>
                   <td><xsl:value-of select="."/></td>
                </tr>
             </xsl:for-each>
          </table>
       </xsl:if>
</xsl:template>

<!-- Preceding-sibling axis -->
<xsl:template match="chairman">
   <xsl:if test="preceding-sibling::node()">
      <h2>preceding-siblings of '<xsl:value-of select="name"/>'</h2>
   <table border="1">
         <tr>
            <th>Node name</th>
            <th>Node value</th>
      </tr>
      <xsl:for-each select="preceding-sibling::node()">
          <tr>
            <td><xsl:value-of select="name()"/></td>
             <td><xsl:value-of select="."/></td>
          </tr>
       </xsl:for-each>
       </table>
   </xsl:if>
   <xsl:apply-templates/>
</xsl:template>

<!-- Attribute axis (note: two template rules) -->
<xsl:template match="/">
   <html>
      <head><title>Employee Info</title></head>
           <body>
            <table border="1">
            <tr>
               <th>Name</th>
               <th>Emp ID</th>
               <th>Empl Date</th>
            </tr>
            <xsl:apply-templates />
         </table>
           </body>
   </html>
</xsl:template>

<xsl:template match="name">
   <tr>
      <td><xsl:value-of select="."/></td>
      <td><xsl:value-of select="parent::*/attribute::empID"/></td>
      <td><xsl:value-of select="parent::*/attribute::empdate"/></td>
   </tr>
</xsl:template>

<!-- Self axis -->
<xsl:template match="president[division='International']">
   <xsl:for-each select="descendant::name">
      <h2><xsl:value-of select="self::*"/></h2>
   </xsl:for-each>
</xsl:template>

<!-- Descendant-or-self axis -->
<xsl:template match="name[.='Steve Masters']">
   <h2>Steve Masters and descendant elements:</h2>
   <table border="1">
      <tr>
         <th>Name</th>
         <th>Emp ID</th>
         <th>Empl Date</th>
      </tr>
      <xsl:for-each select="parent::*/descendant-or-self::name">
         <tr>
            <td><xsl:value-of select="."/></td>
            <td><xsl:value-of select="parent::*/@empID"/></td>
            <td><xsl:value-of select="parent::*/@empdate"/></td>
         </tr>
      </xsl:for-each>
   </table>
</xsl:template>

<!-- Ancestor-or-self axis -->
<xsl:template match="name[.='Josh Barnhill']">
   <h2>Josh Barnhill's reporting structure:</h2>
   <table border="1">
      <tr>
         <th>Generation</th>
         <th>Name</th>
         <th>Emp ID</th>
         <th>Empl Date</th>
      </tr>
      <xsl:for-each select="ancestor-or-self::*[name()!='name']">
         <tr>
            <td align="center">
               <xsl:value-of select="position()-last()"/>
            </td>
            <td><xsl:value-of select="name"/></td>
            <td><xsl:value-of select="@empID"/></td>
            <td><xsl:value-of select="@empdate"/></td>
         </tr>
      </xsl:for-each>
   </table>
</xsl:template>

</xsl:stylesheet>


Filtering XML Data Using XPath Predicates

This section covers the following:

  • Introduction to Filtering with XPath Predicates
  • Testing within a Predicate by Using Boolean Operators
  • Testing the Context Position by Using a Numeric Shortcut
  • Specifying Multiple Predicates in a Single XPath Step


Introduction to Filtering with XPath Predicates

An XPath location path consists of one or more location steps, delimited by slashes. For example:

/child::book/child::chapter/attribute::date_written

is an XPath location path which returns a node-set consisting of all date_written attributes of those <chapter> elements which themselves are children of the root <book> element.

Note This example could also be expressed using XPath's abbreviated syntax as:
/book/chapter/@date_written
Remaining examples in this topic will use the abbreviated syntax. For more information, see Using Abbreviations in XPath Expressions.

In general, the purpose of a location path is to return a set of one or more nodes—a node-set—meeting specified criteria. Each location step in the location path consists of an axis (explicit or defaulted to child::) relative to the context node, a node test, and an optional predicate. (The above example does not include a predicate in any of the three location steps.) All nodes which meet all criteria specified by the full location path are returned by the expression.

The general format of a predicate in a location step is:

[condition]

where the square brackets, [ and ], are required, and condition represents some test typically resulting in a Boolean true or false value. The condition usually takes the form:

value operator value

If a particular condition itself may be represented as a Boolean true or false value, the predicate can take a simpler form:

[value]
Note This simplified form of the predicate is very important in limiting a location path only to nodes which have other nodes along a particular axis. If there are any nodes of the given name or type along the indicated axis, the result is true; if there are no such nodes, the result is false. Thus:
chapter[descendant::figure]
selects <chapter> elements which are children of the context node only if they have any descendant <figure> elements.

As an example, the set of nodes returned by the location path at the beginning of this topic could be further limited as follows:

/book/chapter[position()&gt;1]/@date_written[.="2001-05-12"]

This location path can be read, from left to right:

  1. Locate the root <book> element (/book).
  2. Locate all <chapter> elements but the first, in document order, which are children of the root <book> element located by step #1 (chapter[position()&gt;1]).
    Note A predicate, like everything else in an XML document, must adhere to XML rules for well-formed documents. Therefore, operators such as > (in this example), <, and &, which have special meaning to XML parsers, must be escaped using entity references such as &gt;, &lt;, and &amp; respectively.
  3. For the <chapter> elements selected by step #2, locate all of their date_written attributes whose values equal the string "2001-05-12" (@date_written[.="2001-05-12"]).

The result of evaluating this location path is a node-set consisting of the date_written attributes (if any) meeting all these criteria. If no date_written attributes meet the criteria, the result is an empty node-set.

White space between the value and operator terms in a predicate is not significant. Thus, the following two predicates produce the same result:

[position()   =   1]
[position()=1]

See Also

Using XPath Axes to Navigate through XML Data | Determining the Context Node | Constructing the Node-Test Portion of a Location Step


Testing within a Predicate by Using Boolean Operators

As a general rule, the predicate of a location step narrows the range of candidate nodes located by the step to just those that meet the condition specified by the predicate.

The result of such a condition is always a Boolean true or false value. Therefore, the complete syntax for predicates allows you to use a number of standard Boolean operators to compare two values. The table below summarizes these operators:

Operator | Description
= | If values to left and right of the "=" are equal, the result is true; otherwise the result is false.
!= | If values to left and right of the "=" are not equal, the result is true; otherwise the result is false.
&lt; | If value to the left of the "&lt;" is less than value to the right, the result is true; otherwise the result is false.
&gt; | If value to the left of the "&gt;" is greater than value to the right, the result is true; otherwise the result is false.
&lt;= | If value to the left of the "&lt;=" is less than or equal to value to the right, the result is true; otherwise the result is false.
&gt;= | If value to the left of the "&gt;=" is greater than or equal to value to the right, the result is true; otherwise the result is false.
test1 and test2 | If the results of both test1 and test2 are true, then the result of the test as a whole is true; otherwise the result is false.
test1 or test2 | If the result of either test1 or test2 is true, then the result of the test as a whole is true; otherwise the result is false.

A predicate must adhere to XML's rules for well-formed documents. Therefore, operators such as >, <, and &, which have special meaning to XML parsers, must be escaped using entity references such as &gt;, &lt;, and &amp; respectively.

Example

This example is used to demonstrate the operators shown below.

XML File (book_qse.xml)

See Sample XML Data File for Boolean Operators in Predicates. This document represents a book, titled Quantum Superstring Electrodynamics for Newbies, which consists of two chapters. Each chapter contains two sections of text, intermingled with footnote references and pointers to illustrations; following the last <section> element in each chapter is a list of the footnotes referred to in the text. Footnotes will be numbered sequentially from the beginning of the book to the end.

XSLT File (predicate.xsl)

See Sample XSLT File for Boolean Operators in Predicates.

Portions of this example style sheet which are relevant to the discussion of XPath predicates are reproduced below. The example style sheet includes many match and select patterns which could be replaced with more concise or efficient forms. Some of these patterns are also artificial, such as those which select for paragraphs beginning with certain letters of the alphabet. The style sheet's main purpose is to demonstrate various forms of XPath predicates, not to serve as an example of well-tuned XSLT code.

Formatted Output

See Sample Output for Boolean Operators in Predicates.

The = operator

Use an equals sign (=) in a predicate when you need to test whether one value exactly equals another. For instance:

<xsl:when test="parent::*[name()='chapter']">

locates the parent of the context node only when that parent is named "chapter".

The != operator

Use the "not-equals" operator (!=) in a predicate when you need to test whether two values are not equal. For instance:

<xsl:template match="title[name(..)!='book']">

locates a <title> child of the context node only if that child's parent (that is, the context node itself) is not named "book".

Note The != operator can sometimes be used interchangeably with the XPath not() function. For instance, these two predicates are interchangeable:
[name()!='book']
[not(name()='book')]
In such cases, which form of the test you use is a matter of taste. However, the two forms are not always identical—particularly when one of the values on either side of the operator is a node-set. For more information about the not() function, see Testing an Expression by Using Boolean Functions.

The &lt; operator

Use the "less-than" operator in a predicate when you need to test whether one value is less than another. For instance:

<xsl:template match="chapter[position()&lt;2]">

locates a <chapter> child of the context node when that child is at an ordinal position less than 2 (i.e., when it is in the first position) among the current node-set.

The &gt; operator

Use the "greater-than" operator in a predicate when you need to test whether one value is greater than another. For instance:

<xsl:template match="chapter[position()&gt;1]">

locates a <chapter> child of the context node only if that child is greater than the first such child (that is, the second child, third child, and so on), in document order.

The &lt;= operator

Use the "less than or equals" operator in a predicate when you need to test whether one value is less than or equal to another. For instance:

<xsl:template match="@copyright[.&lt;=2000]">

locates all copyright attributes with a value of 2000 or less.

The &gt;= operator

Use the "greater than or equals" operator in a predicate when you need to test whether one value is greater than or equal to another. For instance:

<xsl:template match="@copyright[.&gt;=2001]">

locates all copyright attributes with a value of 2001 or greater.

The "and" operator

Use the "and" operator in a predicate when you need to perform more than one test in order to select from among candidate nodes. All of the tests joined by the "and" must be true in order for the selection to occur. For instance:

<xsl:template match="text[substring(.,1,1)!='T' and substring(.,1,1)!='B'
and substring(.,1,1)!='A' and substring(.,1,1)!='P']">

This match pattern locates all <text> elements which start with anything except the letters "T," "B," "A," or "P." <text> elements beginning with any of those four letters will not be located.

The "or" operator

Use the "or" operator in a predicate when you need to perform any of several tests in order to select from among candidate nodes. Any of the tests joined by the "or" can be true in order for the selection to occur. For instance:

<xsl:template match="text[substring(.,1,1)='T' or substring(.,1,1)='B' or
substring(.,1,1)='A' or substring(.,1,1)='P']">

This match pattern locates all <text> elements which start with any of the letters "T," "B," "A," or "P." <text> elements beginning with any other characters will not be located.


Sample XML Data File for Boolean Operators in Predicates

For more information about this file, see Testing within a Predicate by Using Boolean Operators.

XML File (book_qse.xml)

<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="predicate.xsl"?>
<book copyright="2001">
    <title>Quantum Superstring Electrodynamics for Newbies</title>
    <chapter date_written="2000-11-03">
        <title>QSE Background</title>
        <section>
            <title>History</title>
            <text>The history of quantum superstring...<noteref idref="def_ed"/></text>
            <text>On the other hand...<noteref idref="clarif_01"/></text>
            <text>Still,...</text>
        </section>
        <section>
            <title>First Principles</title>
            <text>Before proceeding further...<noteref idref="Feyn"/></text>
            <text>We will see many examples...</text>
        </section>
        <notes>
            <note id="def_ed">The term "electrodynamics" refers to...</note>
            <note id="clarif_01">Not to be confused with...</note>
            <note id="Feyn">Or, as Feynman once said...</note>
        </notes>
    </chapter>
    <chapter date_written="2000-12-16">
        <title>Quanta</title>
        <section>
            <title>Packaging the Lightning</title>
            <text>A "quantum," basically, represents...<noteref idref="exp_01"/></text>
            <text>Yes, it is true that we cannot draw conclusions from such a...</text>
        </section>
        <section>
            <title>Quanta within Quanta</title>
            <text>Picture a set of nested boxes, such as Figure 1:
            <figure location="media/figure_01.png"
                caption="Figure 1: Boxes within boxes within boxes..."/></text>
            <text>What do we mean when we say...?<noteref idref="clarif_02"/></text>
            <text>...as we shall see over the next five to ten exciting years.</text>
        </section>
        <notes>
            <note id="exp_01">Try it yourself! Take your laser...</note>
            <note id="clarif_02">Don't let the term "poison" alarm...</note>
        </notes>
    </chapter>
</book>


Sample XSLT File for Boolean Operators in Predicates

XSLT File (predicate.xsl)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://www.w3.org/TR/REC-html40" >

<xsl:output method="html" />

<!-- Override built-in template rules for elements
and text nodes (note empty <xsl:template element). -->
<xsl:template match="*" />

<!-- Process the document root. -->
<xsl:template match="/">
    <html>
    <head><title><xsl:value-of select="book/title"/></title></head>
    <h1><xsl:value-of select="book/title"/></h1>
    <body>
        <xsl:apply-templates/>
    </body>
    </html>
</xsl:template>

<xsl:template match="book">
    <xsl:apply-templates select="@*|*"/>
</xsl:template>

<xsl:template match="@copyright[.&gt;=2001]">
    <cite>
        [Copyright <xsl:value-of select="."/>
        (21st century)]
    </cite>
</xsl:template>

<xsl:template match="@copyright[.&lt;=2000]">
    <cite>
        [Copyright <xsl:value-of select="."/>
        (Previous century)]
    </cite>
</xsl:template>

<xsl:template match="book[not(@copyright)]">
    <cite>
        [No copyright date supplied]
    </cite>
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="chapter[position()&lt;2]">
    <hr />
    <hr />
    <div style="background-color: teal">
        <h2 align="right">Chapter <xsl:value-of select="position()-2"/>:</h2>
        <xsl:apply-templates select="title"/>
    </div>
    <xsl:apply-templates select="section|notes"/>
</xsl:template>

<xsl:template match="chapter[position()&gt;1]">
    <hr />
    <div style="background-color: teal">
        <h2 align="right">Chapter <xsl:value-of select="position()-2"/>:</h2>
        <xsl:apply-templates select="title"/>
    </div>
    <xsl:apply-templates select="section|notes"/>
</xsl:template>

<xsl:template match="title[name(..)!='book']">
    <xsl:choose>
        <xsl:when test="parent::*[name()='chapter']">
            <h2 align="right"><xsl:value-of select="."/></h2>
        </xsl:when>
        <xsl:otherwise>
            <div style="background-color: silver">
                <h3 align="left"><xsl:value-of select="."/></h3>
            </div>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="section">
    <xsl:apply-templates />
</xsl:template>

<xsl:template match="notes">
    <hr width="75%" align="left" />
    <h4>Notes for this chapter:</h4>
    <xsl:apply-templates select="note"/>
</xsl:template>

<xsl:template match="note">
    <p><a name="#{@id}" />[<xsl:value-of select="count(preceding::note[ancestor::chapter//.])+1"/>] <xsl:value-of select="text()"/></p>
</xsl:template>

<xsl:template match="noteref">
  <xsl:variable name="note_num" select="count(preceding::noteref[ancestor::chapter//.])+1"/>
          [<a href="#{@idref}">Note <xsl:value-of select="$note_num"/></a>]
</xsl:template>

<xsl:template match="figure">
    <br clear="left" />
    <img border="1" height="200" width="200" alt="{@caption}" src="{@location}" />
    <br clear="left" />
</xsl:template>

<xsl:template match="text[substring(.,1,1)='T' or substring(.,1,1)='B' or substring(.,1,1)='A' or substring(.,1,1)='P']">
    <p><span style="font-weight: bold; font-size: 18pt; font-family=Verdana,Arial">
        <xsl:value-of select="substring(.,1,1)"/>
        </span>
        <xsl:value-of select="substring(., 2, string-length(.)-1)"/>
        <xsl:apply-templates select="noteref|figure"/>
    </p>
</xsl:template>

<xsl:template match="text[substring(.,1,1)!='T' and substring(.,1,1)!='B' and substring(.,1,1)!='A' and substring(.,1,1)!='P']">
    <p>
        <xsl:apply-templates select="noteref|figure|text()"/>
    </p>
</xsl:template>

</xsl:stylesheet>


Sample Output for Boolean Operators in Predicates

Formatted Output

The top portion of the formatted output is shown here.

Processor Output

<html xmlns="http://www.w3.org/TR/REC-html40">
<head><title>Quantum Superstring Electrodynamics for Newbies</title></head>
<h1>Quantum Superstring Electrodynamics for Newbies</h1>
<body>
<cite>
  [Copyright 2001
  (21st century)]
 </cite>
<hr/>
<hr/>
<div style="background-color: teal">
<h2 align="right">Chapter 1:</h2>
<h2 align="right">QSE Background</h2>
</div>
...
<p>...as we shall see over the next five to ten exciting years.</p>
<hr width="75%" align="left"/>
<h4>Notes for this chapter:</h4>
<p><a name="#exp_01"/>[4] Try it yourself! Take your laser...</p>
<p><a name="#clarif_02"/>[5] Don't let the term "poison" alarm...</p>
</body>
</html>


Testing the Context Position by Using a Numeric Shortcut

In most cases, an XPath predicate has a Boolean value true or false, resulting from the test contained within the [ and ] characters.

A common test appearing in predicates compares the context position to some value. For instance:

chapter[position()=1]

selects the first <chapter> element which is a child of the context node.

XPath provides a convenient shortcut for this common sort of test: simply use the number of the position you want to test. For example, the following behaves exactly like the above:

chapter[1]

The value of the predicate need not be a literal number. It can also be a reference to a variable which has a numeric value, for example, or the value of the number() function applied to some node or text string. Therefore, both of the forms below also demonstrate acceptable uses of this shortcut:

chapter[$xref]
chapter[number("12")]

Note that this shortcut is available only for testing whether the context position is equal to some constant value. There is no similar shortcut for testing greater-than, not-equal-to, and similar conditions.

See Also

Determining the Context Position


Specifying Multiple Predicates in a Single XPath Step

An XPath location step will usually include only a single predicate. Under certain circumstances, however, it may be necessary to further filter the node-set returned by the first predicate, within a single XPath location step.

For example:

chapter[@author="Niikkonen, Donna"][1]

locates the first <chapter> child of the context node for which the <chapter>'s author attribute has the value "Niikkonen, Donna" (i.e., the first chapter written by Donna Niikkonen).

When using multiple predicates, you must be careful to place them in the right order. The above does not necessarily produce the same result as:

chapter[1][@author="Niikkonen, Donna"]

which always selects the first chapter, then tests whether that was or was not written by Donna Niikkonen and selects or rejects it accordingly.


Using Functions in XPath Expressions

The XPath standard defines functions which can manipulate the content of the source tree in various ways.

This section covers the following:

  • Introduction to XPath Functions
  • Processing Node-Sets by Using Node-Set Functions
  • Processing Text Strings by Using String Functions
  • Testing an Expression by Using Boolean Functions
  • Using Numeric Functions to Perform Math Operations in XPath
  • Using Numeric Operators to Perform Math Operations in XPath
  • Using XSLT Functions in XPath Expressions
  • Sample XML Data File for XPath Functions


Introduction to XPath Functions

A function in XPath, as in most programming languages, is a built-in software routine which performs some operation and returns some value. The returned value effectively replaces the reference (or call) to the function which appears at a given point in the code.

A reference to a function takes the form:

functionname(arg1...)

where:

  • functionname is the name of the function;
  • the parentheses are required; and
  • arg1... is a comma-separated list of values, called arguments, which are used by the function to perform its work. (Note that not all functions take arguments, and in some cases arguments may or may not be required, depending on the circumstances.)

As an example, the XPath specification defines a function whose name is contains. This function takes two arguments, both of them string values. If the first string contains the second string, the function returns the value True; otherwise, it returns False. For more information about contains(), see Processing Text Strings by Using String Functions.

Consider the following XML fragment:

<book>
    <chapter><heading>Help for Lost XPathians</heading></chapter>
    <chapter><heading>Searching and Sorting</heading></chapter>
    <chapter><heading>Where to Find Help</heading></chapter>
</book>

and the following XPath location path:

//chapter[heading][contains(., "Help")]

This location path selects all <chapter> elements with a <heading> child which contains the string "Help"—that is, it selects the first and third <chapter> elements. The function call, contains(., "Help"), is replaced by the value True for <chapter> elements which contain the desired text string, and by False for all others.

Note The "." in the call to the contains() function here forces the context node to be converted to its string value.


Processing Node-Sets by Using Node-Set Functions

The XPath node-set functions perform operations on (as the name implies) node-sets which have been located at the moment the function call is made.

In the following table, which summarizes these node-set functions, ns represents a node-set passed as an argument; ns? represents an optional node-set argument; and obj represents an object of some arbitrary type, such as node-set or string.

Format | Description/Example
last() | Returns the number of the last node in the currently selected node-set
position() | Returns the number of the current node in the selected node-set. Note: [position()=some number] as an expression's predicate can be abbreviated as [some number]; for example, [position()=3] can be shortened to simply [3].
count(ns) | Returns the number of nodes in the node-set passed to the function.
id(obj) | Returns the node with the ID-type attribute whose value equals that of obj; if the latter is a string, see the description of the string() function for how the value is converted.
local-name(ns?) | Returns the "local name" of the argument. The full name of an element is considered to be its expanded name—that is, including the prefix associated with its namespace, if there is one. The local name is this "full name" with the namespace prefix omitted.
namespace-uri(ns?) | Returns the URI associated with the argument's namespace, if there is one.
name(ns?) | Returns the "full name" of an element, including its namespace prefix (if any).

last()

This location path:

/sales/region[last()]/units

returns the number of units sold by the last region in the document, or 465.

The last() function is similar to the count() function in that both return the number of nodes in a given node-set. The difference is that last() always operates on the node-set in effect at the time of the function call, while count() requires that a node-set be supplied to it.

position()

The location path:

/sales/region[position()=2]/@name

returns the value of the name attribute for the second region in the document, or "Southeast."

count(ns)

This XPath expression:

count(/sales/region)

returns the number of <region> elements that are children of the root <sales> element, or 4.

The count() function is similar to the last() function in that both return the number of nodes in a given node-set. The difference is that last() always operates on the node-set in effect at the time of the function call, while count() requires that a node-set be supplied to it.

id(obj)

You could determine the amount associated with sales in the Northwest region with the following:

//*[id("Northwest")]/amount

This navigates down to the element of any name with an ID-type attribute whose value is "Northwest," and locates the value of the corresponding <amount> element, or 12500.26.

local-name(ns?)

The Sample XML Data File for XPath Functions doesn't include any namespace declarations. Even if it did, though, the following XSLT template:

<xsl:for-each select="//region[2]/*">
    <xsl:value-of select="local-name()"/>
</xsl:for-each>

would simply display the local names of all child elements of the second <region> element as a single string, or "unitsamount".

Note that the local-name() function always extracts the simple name(s) of a given node-set (the context node, by default), and therefore always "works" regardless of the presence or absence of namespace declarations. The name() function, on the other hand, always refers to nodes by their fully-qualified names, including any namespace prefixes.

namespace-uri(ns?)

Our sample document doesn't include any namespace declarations. However, consider the case of an XSLT style sheet which begins with the following <xsl:stylesheet> element:

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

If a separate style sheet were applied to this one, containing the following template rule:

<xsl:template match="/xsl:stylesheet">
    <xsl:value-of select="namespace-uri()"/>
</xsl:template>

the result would be the URI in effect for the <xsl:stylesheet> element, or "http://www.w3.org/1999/XSL/Transform".

name(ns?)

Our sample document doesn't include any namespace declarations. For this reason, all element names returned by the name() function will be identical to those returned by the local-name() function. However, consider an XSLT style sheet for transforming XML data to HTML; such a style sheet typically opens with this <xsl:stylesheet> element:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="xmlns="http://www.w3.org/TR/REC-html40">

If you transformed this style sheet using a separate one containing the following template rule:

<xsl:template match="/xsl:stylesheet">
    <pre>
    <p>
            local-name(): <xsl:value-of select="local-name()"/>
    </p>
    <p>
        name(): <xsl:value-of select="name()"/>
    </p>
</pre>
</xsl:template>

the output, when viewed in Internet Explorer, would be:

local-name(): stylesheet
name(): xsl:stylesheet

Note that name() returns the full name, including namespace prefix.

See Also

Sample XML Data File for XPath Functions | Processing Text Strings by Using String Functions


Processing Text Strings by Using String Functions

The XPath string functions perform a wide variety of operations on text-string values.

In the following table, which summarizes the string functions, str represents a string passed as an argument; str*, a set of zero or more strings, delimited by commas; obj, an object of some arbitrary type, such as node-set or number; and num, an integer number. The character ? appended to any of these argument types means that the argument is completely optional. If a function has only a single optional argument which is omitted in a given call, the function is assumed to apply to the context node.

Format | Description/Example
string(obj?) | Converts the argument to a string value, which is then returned from the function.
concat(str, str, str*) | Concatenates the various strings passed to it into a single string, which is returned from the function.
starts-with(str, str) | Returns "true" if the first argument starts with the second, otherwise "false".
contains(str, str) | Returns "true" if the first argument contains the second, otherwise "false".
substring(str, num, num?) | Extracts a portion of the first argument, starting with the position supplied by the second argument, for a length of however many characters are in the third argument (if there is one). If the third argument is omitted, the function simply returns all characters in the first argument, starting at the position supplied by the second.
substring-before(str, str) | Returns the portion of the first argument that precedes the value of the second argument.
substring-after(str, str) | Returns the portion of the first argument that follows the value of the second argument.
string-length(str?) | Returns the number of characters in the argument. If the argument is omitted, returns the number of characters in the current node.
normalize-space(str?) | Examines the argument and strips out leading and trailing whitespace in it; also removes extraneous whitespace within the argument by replacing two or more occurrences of whitespace with a single space. The value returned by the function is this "stripped" string.
translate(str, str, str) | Returns the first argument, replacing each occurrence of a character that matches one of the characters in the second argument with the character in the corresponding position in the third argument.

string(obj?)

When applied to the root element of our sample document, the following XPath expression:

string(*)

returns a single string containing a (space-delimited ) list of the entire document's text contents, or "374 12500.26 512 17692 161 8349.72 465 15239.6".

concat(str, str, str*)

We could produce a list of the regions in the sample document, including a label which varies by the region's position in the document, using an XSLT template rule such as:

<xsl:template match="sales">
    <xsl:for-each select="region">
        <h3>
<xsl:value-of select="concat('Region ', string(position()), ': ', @name)"/>
</h3>
    </xsl:for-each>
</xsl:template>
Note The above template rule forces the value of the position() function, normally a number, to be converted to a string. In practice this is not necessary, since numbers are coerced to strings when needed by all these string-handling features. For more information about the position() function, see Processing Node-Sets by Using Node-Set Functions.

When viewed in Internet Explorer, this template rule displays:

Region 1: Northeast
Region 2: Southeast
Region 3: Southwest
Region 4: Northwest

starts-with(str, str)

This XPath location path:

//region[starts-with(@name, 'S')]

locates all <region> elements in the document whose name attributes start with the letter "S", or in this case the Southeast and Southwest regions.

contains(str, str)

The location path:

//region[contains(@name, 'east')]

locates all <region> elements in the document whose name attributes contain the string "east", or in this case the Northeast and Southeast regions.

substring(str, num, num?)

We could derive region name abbreviations for the four regions in our sample document using the following XSLT template rule:

<xsl:template match="region">
    <h3><xsl:value-of select="substring(@name, 1, 1)"/>
    <xsl:choose>
        <xsl:when test="contains(@name, 'west')">W</xsl:when>
        <xsl:otherwise>E</xsl:otherwise>
    </xsl:choose></h3>
</xsl:template>

The call to the substring() function returns the first letter in the <region> element's name attribute. The <xsl:choose> block then displays either a "W" or an "E" depending on whether the name contains the string "west" or not, respectively.

Internet Explorer displays the results of this template rule as:

NE
SE
SW
NW

substring-before(str, str)

To display whether a region lies in the northern or southern areas, you could use the substring-before() function as shown in the following sample.

Example

XML File (xpathfuncs.xml)

Change the href attribute in xpathfuncs.xml (shown in Sample XML Data File for XPath Functions) to reference funcsubstringbef.xsl.

XSLT File (funcsubstringbef.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="region">
    <h3>Region "<xsl:value-of select="@name"/>" is in the
        <xsl:choose>
            <xsl:when test="contains(@name, 'west')">
                <xsl:value-of select="substring-before(@name, 'west')"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="substring-before(@name, 'east')"/>
            </xsl:otherwise>
        </xsl:choose>
    </h3>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Region "Northeast" is in the North

Region "Southeast" is in the South

Region "Southwest" is in the South

Region "Northwest" is in the North

Processor Output

<?xml version="1.0" encoding="UTF-16"?><h3>Region "Northeast" is in the
        North</h3><h3>Region "Southeast" is in the
        South</h3><h3>Region "Southwest" is in the
        South</h3><h3>Region "Northwest" is in the
        North</h3>

substring-after(str, str)

You could invert the example used above, for the substring-before() function, to display whether a region is located in the eastern or western sales districts. To do so, you could use an XSLT template rule such as shown in the sample below.

In this example, unlike the parallel one for substring-before(), the name of the district ("east" or "west") is not capitalized. If you wanted to capitalize the district name, you could use the translate() function for this purpose.

Example

XML File (xpathfuncs.xml)

Change the href attribute in xpathfuncs.xml (shown in Sample XML Data File for XPath Functions) to reference funcsubstringaft.xsl.

XSLT File (funcsubstringaft.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="region">
    <h3>Region "<xsl:value-of select="@name"/>" is in the
        <xsl:choose>
            <xsl:when test="contains(@name, 'North')">
                <xsl:value-of select="substring-after(@name, 'North')"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="substring-after(@name, 'South')"/>
            </xsl:otherwise>
        </xsl:choose>ern district
    </h3>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Region "Northeast" is in the eastern district

Region "Southeast" is in the eastern district

Region "Southwest" is in the western district

Region "Northwest" is in the western district

Processor Output

<?xml version="1.0" encoding="UTF-16"?><h3>Region "Northeast" is in the
        eastern district
    </h3><h3>Region "Southeast" is in the
        eastern district
    </h3><h3>Region "Southwest" is in the
        western district
    </h3><h3>Region "Northwest" is in the
        western district
    </h3>

string-length(str?)

Unlike most XPath string functions, string-length() returns a number instead of a string. This number can be used as-is, or (as with other function references) passed as an argument to some other function.

In our sample XML document, notice that the value of some <units> contains a decimal portion, while the others contain integer values. Using this observation and some of the other XPath string functions in conjunction with string-length(), we could select regions which failed to sell an amount of least 10,000 with a template rule as shown in the XSLT sample file below.

First, the template rule defines a variable, amt_integ. This variable will contain either the value of the <amount> element, or that value less the decimal portion, depending on whether or not the value contains a decimal point. The template rule then tests this resulting "integer amount" to see if its string-length is less than 5—that is, if the value of the amt_integ variable is 9999 or less. If so, the region's name and the value of the <amount> element are displayed.

In this particular example, you could have used a much simpler and more direct numeric test against the value of the <amount> element. For example:

<xsl:if test="amount &lt; 10000">

This direct numeric test would obviate the need to use the various string functions demonstrated in this example.

Example

XML File (xpathfuncs.xml)

Change the href attribute in xpathfuncs.xml (shown in Sample XML Data File for XPath Functions) to reference funcstringlen.xsl.

XSLT File (funcstringlen.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="region">
    <xsl:variable name="amt_integ">
        <xsl:choose>
            <xsl:when test="contains(amount, '.')">
                <xsl:value-of select="substring-before(amount, '.')"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="amount"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:if test="string-length($amt_integ)&lt;5">
        <h3>
            <xsl:value-of select="@name"/> Region's sales only
            <xsl:value-of select="amount"/> this quarter.
        </h3>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Southwest Region's sales only 8349.72 this quarter.

Processor Output

<?xml version="1.0" encoding="UTF-16"?><h3>Southwest Region's sales only
            8349.72 this quarter.
        </h3>

normalize-space(str?)

This XPath string function is particularly useful when comparing two strings which possibly contain leading or trailing white space, especially newlines, which you might otherwise overlook in a source document.

For instance, consider the following two <sample> elements:

<sample>Now is the time...
</sample>

and:

<sample>Now is the time...</sample>

Any template in the following <xsl:if> element will not be instantiated:

<xsl:if test="sample[1]=sample[2]">

The trailing newline in the first <sample> is part of its content, so its string-value does not equal that of the second <sample>. For an accurate comparison between the two elements' contents, use this instead:

<xsl:if test="normalize-space(sample[1])=normalize-space(sample[2])">

translate(str, str, str)

To convert the names of the regions in our sample document to all uppercase, you could use the following:

translate(//region/@name, "abcdefghijklmnopsqrtuvwxyz",
"ABCDEFGHIJKLMNOPSQRTUVWXYZ")

The translate() function scans the first argument--the value of the given <region> element's name attribute, in this case—looking for any of the individual characters in the second argument. For each matched character, the function substitutes the character from the third argument in the same position as the matched character. So each "a" becomes "A", each "b" becomes "B", and so on. The translated result is returned by the function, giving (in this case) "NORTHEAST", "SOUTHEAST", and so on.

Note Any characters which do not appear in the second argument, such as the capital "N" and "S" in the various region names, are retained in the resulting string with no substitution made.
Also note that if the second argument contains more characters than the third, the effect will be to remove the missing characters in the returned value. For instance:
translate("Internet", "nter", "NTE")
will substitute a capital "N", "T", and "E" for the corresponding characters in the second string, but replace the lowercase "r" with nothing at all, i.e. remove it from the input string. The result is:
INTENET

Example

XML File (xpathfuncs.xml)

Change the href attribute in xpathfuncs.xml (shown in Sample XML Data File for XPath Functions) to reference functranslate.xsl.

XSLT File (functranslate.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="sales">
   <xsl:value-of select='translate(//region/@name,
"abcdefghijklmnopsqrtuvwxyz", "ABCDEFGHIJKLMNOPSQRTUVWXYZ")'/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

NORTHEAST

Processor Output

<?xml version="1.0" encoding="UTF-16"?>NORTHEAST


Testing an Expression by Using Boolean Functions

The XPath Boolean functions return simple true or false values based on the functions' evaluation of arguments (if any) passed to them.

In the following table, which summarizes the Boolean functions, str represents a string passed as an argument; obj, an object of some arbitrary type, such as node-set or number; and boolean, a Boolean condition (with either a true or false value).

Format | Description/Example
boolean(obj) | Used primarily to test whether or not something "exists." If obj is a node-set, the function returns true if and only if the node-set is not empty; if a string, if and only if the string's length is greater than 0; and if a number, if and only if it is non-zero and a valid number. In all other cases it returns false.
not(boolean) | Returns true if the argument passed to it is false, or false if the argument passed to it is true.
true() | Simply returns the value true.
false() | Simply returns the value false.
lang(str) | Returns true or false, depending on whether or not the context node has the xml:lang value specified in str.

Note The true() and false() functions generally make explicit what is otherwise implicit in an XPath expression. This is useful primarily for ensuring that your meaning is clear, as in the following:
<xsl:if test="(x=y)=true()">
which could also be represented, more simply:
<xsl:if test="x=y">
However, these two functions may also be used to assign Boolean values to XSLT variables. Examples of this use are shown below.

boolean(obj)

To verify that the value of the <units> element is a number before performing some numeric operation on it, you could use the following:

<xsl:if test="boolean(number(units))">

If the <units> element is empty or contains a non-numeric value, the body of the <xsl:if> element will not be executed.

Note The preceding is not the same as:
<xsl:if test="boolean(units)">
This simpler test passes the <units> element as a node-set (not its value as a number) to the function, and thus simply verifies that the context node has at least one <units> child.

not(boolean)

The following expression determines whether the document has any <amount> elements whose values are greater than 20,000:

not(amount[. &gt; 20000])

If there are any such <amount> elements, the function returns false, otherwise true.

The not() function appearing in a predicate or XSLT test can sometimes be used interchangeably with the != Boolean operator. For example:

[not("A"="B")]

and

["A"!="B"]

are functionally equivalent.

However, when one of the two values being compared is a node-set, using the not() function vs. the != operator can produce different results, as shown in the sample below.

Consider the two XSLT <xsl:if> elements in the sample XSLT template rule shown below.

The first test outputs "Not March 03" for both invoices. Essentially, it asks the question: "Does the context node have an invoice_date attribute, and if it does, does the attribute's value not equal '2001-03-04'?"

The second outputs "Not March 03" for invoice #X00456 only, because it asks a slightly different question: "Does the context node not have an invoice_date attribute which equals '2001-03-04?" The answer to that question is true for only the <sale> element whose invoice number is X00456.

For more information about the != operator, see Testing within a Predicate by Using Boolean Operators.

Example

XML File (funcnot.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="funcnot.xsl" ?>
<sales copyright="2001">
   <sale invoice="X00123" invoice_date="2001-01-05"/>
   <sale invoice="X00456"/>
</sales>

XSLT File (funcnot.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="sales">
   <xsl:for-each select="sale">
      <p><b>For invoice #<xsl:value-of select="@invoice"/></b></p>
      <xsl:if test="@invoice_date!='2001-03-04'">
         <p>Test with "!=": Not March 03</p>
      </xsl:if>
      <xsl:if test="not(@invoice_date='2001-03-04')">
         <p>Test with "not()": Not March 03</p>
      </xsl:if>
   </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Formatted Output

For invoice #X00123
Test with "!=": Not March 03
Test with "not()": Not March 03
For invoice #X00456
Test with "not()": Not March 03

Processor Output

The XSLT produces the following stream. Line breaks have been added for clarity.

<?xml version="1.0" encoding="UTF-16"?>
<p><b>For invoice #X00123</b></p>
<p>Test with "!=": Not March 03</p>
<p>Test with "not()": Not March 03</p>
<p><b>For invoice #X00456</b></p>
<p>Test with "not()": Not March 03</p>

true() and false()

You can define a variable which returns a true or false value depending on some condition in the document being processed, as in the example below.

The explicit test of the string value "true" in the <xsl:if> element above is necessary because the <xsl:value-of> element in the $units_gt_300 variable's definition returns a result tree fragment (RTF), which—regardless of the actual data type of the RTF's value—is always treated as a string. If we hadn't been concerned with demonstrating the use of the true() and false() functions, the variable's definition could be more concisely expressed as:

<xsl:variable name="units_gt_300" select="number(units) &gt; 300"/>

This would have returned a pure Boolean true or false value. So the <xsl:if> element could more simply have been coded:

<xsl:if test="$units_gt_300">

For more information, see Introduction to Result Tree Fragments.

Example

XML File (xpathfuncs.xml)

Change the href attribute in xpathfuncs.xml (shown in Sample XML Data File for XPath Functions) to reference the above XSLT file.

XSLT File (functruefalse.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="sales">
    <h2>Regions Selling More than 300 Units:</h2>
    <xsl:for-each select="region">
    <xsl:variable name="units_gt_300">
        <xsl:choose>
            <xsl:when test="number(units) &gt; 300">
                <xsl:value-of select="true()"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="false()"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:if test="$units_gt_300='true'">
        <h3><xsl:value-of select="concat(@name, ' (', units, ' units)')"/></h3>
    </xsl:if>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

<?xml version="1.0" encoding="UTF-16"?>
<h2>Regions Selling More than 300 Units:</h2>
<h3>Northeast (374 units)</h3>
<h3>Southeast (512 units)</h3>
<h3>Northwest (465 units)</h3>

lang(str)

Consider an XML document such as the following:

<?xml version='1.0'?>
<dict>
    <translate>
        <word xml:lang="DE">Ma&#xDF;einheiten</word>
        <word xml:lang="EN">units</word>
        <word xml:lang="ES">unidades</word>
        <word xml:lang="FR">unit&#xE9;s</word>
        <word xml:lang="IT">unit&#xE8;</word>
        <word xml:lang="PT">unidades</word>
    </translate>
    <translate>
        <word xml:lang="DE">Verk&#xE4;ufe</word>
        <word xml:lang="EN">sales</word>
        <word xml:lang="ES">ventas</word>
        <word xml:lang="FR">ventes</word>
        <word xml:lang="IT">vendite</word>
        <word xml:lang="PT">vendas</word>
    </translate>
</dict>

An XSLT style sheet to demonstrate a general-purpose "translation" feature might accept two parameters from the user: a word to be translated (held in the parameter called $xlate_word), and a two-character code for the language into which the word is to be translated (the parameter $xlate_lang). Such a style sheet might contain the template rule shown in the sample below.

The template rule's <xsl:for-each> element extracts the <word> element which matches the input word. It then displays the following:

  • The input word
  • The language code which corresponds to the input word
  • The input language code
  • The translated value

Note that the translated value is derived (in the final <xsl:select>) first by locating the parent of the <word> element whose value matches the input word, then by locating the child of that parent whose xml:lang attribute matches the input language code.

With the word "units" and the language code "DE" passed as parameters into the style sheet, Internet Explorer displays this template rule's results as follows:

Input word is: units
Its language code is: EN
Translating to DE...
Translated value is: Maßeinheiten

Example

XML File (funclang.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="funclang.xsl" ?>
<dict>
    <translate>
        <word xml:lang="DE">Ma&#xDF;einheiten</word>
        <word xml:lang="EN">units</word>
        <word xml:lang="ES">unidades</word>
        <word xml:lang="FR">unit&#xE9;s</word>
        <word xml:lang="IT">unit&#xE8;</word>
        <word xml:lang="PT">unidades</word>
    </translate>
    <translate>
        <word xml:lang="DE">Verk&#xE4;ufe</word>
        <word xml:lang="EN">sales</word>
        <word xml:lang="ES">ventas</word>
        <word xml:lang="FR">ventes</word>
        <word xml:lang="IT">vendite</word>
        <word xml:lang="PT">vendas</word>
    </translate>
</dict>

XSLT File (funclang.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- input parameters for testing -->
<xsl:param name="xlate_word">units</xsl:param>
<xsl:param name="xlate_lang">DE</xsl:param>

<xsl:template match="dict/translate">
    <xsl:for-each select="word[.=$xlate_word]">
        <p>
            Input word is: <xsl:value-of select="$xlate_word"/><br />
            Its language code is: <xsl:value-of select="@xml:lang"/>
        </p>
        <p>
            Translating to <xsl:value-of select="$xlate_lang"/>...<br />
            Translated value is:
<xsl:value-of select="../*[lang($xlate_lang)]"/>
        </p>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Input word is: units
Its language code is: EN
Translating to DE...
Translated value is: Maßeinheiten

Processor Output

<?xml version="1.0" encoding="UTF-16"?><p>
            Input word is: units<br />
            Its language code is: EN</p><p>
            Translating to DE...<br />
            Translated value is:
Maßeinheiten</p>


Using Numeric Functions to Perform Math Operations in XPath

XPath's numeric functions allow you to perform certain basic mathematical operations on given numeric values or node-sets.

Note that simple arithmetic—addition, subtraction, and so on—can be performed using straightforward numeric operations. For more information, see Using Numeric Operators to Perform Math Operations in XPath.

In the following table, which summarizes the numeric functions, obj? is an optional object of some arbitrary type, such as node-set or number, passed into the function; ns, a node-set; and num, an integer number.

Format | Description/Example
number(obj?) | Converts the argument to a number and returns the result. If the argument can't be converted, the function returns the string "NaN" (for "not a number"). If no argument is passed, the function operates on the context node.
sum(ns) | Returns the sum of all nodes in the argument. If you want to simply add numeric values that aren't associated with a node-set, use the + sign as described in the Numeric operations topic.
floor(num) | Returns the largest integer that is less than or equal to the argument.
ceiling(num) | Returns the smallest integer that is greater than or equal to the argument.
round(num) | Rounds the argument's value up or down to the nearest integer. 1.5 always rounds up to 2, and -1.5 always rounds up to -1. Accurate rounding is dependent on hardware and operating-system considerations; you should test a wide range of possible values to be sure that this function returns the results you want in your application.

number(obj?)

The following XPath expression:

number(//region[@name="Northwest"]/units)

simply returns the numeric value 465.

On the other hand, this XPath expression:

number(//region/@name)

returns the string "NaN". This can be useful when you want to perform basic arithmetic operations. If you add two elements' supposedly numeric contents, but one of them is empty or non-numeric, your results will not be what you expected. Thus you could use XSLT logic such as the following to substitute a value of 0 for any such non-numeric values:

<xsl:template match="/sales">
    <xsl:for-each select="region">
    <xsl:variable name="tax_pct">.07</xsl:variable>
    <xsl:variable name="num_sales">
        <xsl:choose>
            <xsl:when test="string(number(amount))='NaN'">0</xsl:when>
            <xsl:otherwise><xsl:value-of select="amount"/></xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <p>
        Region - <xsl:value-of select="@name"/>:<br />
        <xsl:value-of select="format-number($tax_pct * 100, '##0.00')"/>%
        tax on amount of
        <xsl:value-of select="format-number($num_sales, '#,##0.00')"/> is:
        <xsl:value-of select="format-number($num_sales * $tax_pct,'#,##0.00')"/>
    </p>
    </xsl:for-each>
</xsl:template>
Note In order to test the result of the number() function call for a value of "NaN," you must convert that result (as in this template rule) to a string, using the string() function. For more information, see Processing Text Strings by Using String Functions.

If you go back to our sample XML document and replace the value 12500.26 (the value of the Northeast region's <amount> element) with either a non-numeric value or with nothing at all, the above template rule displays in Internet Explorer as:

Region - Northeast:
7.00% tax on amount of 0.00 is: 0.00
Region - Southeast:
7.00% tax on amount of 17,692.00 is: 1,238.44
Region - Southwest:
7.00% tax on amount of 8,349.72 is: 584.48
Region - Northwest:
7.00% tax on amount of 15,239.60 is: 1,066.77

Without the use of the number() function to test for "NaN," the lines for the Northeast region look like this:

Region - Northeast:
7.00% tax on amount of NaN is: NaN

sum(ns)

To display the sum of all regions' sales amounts and units, you could use an XSLT template rule such as:

<xsl:template match="sales">
    <h4>Quarter beginning: <xsl:value-of select="@quarter"/></h4>
    <p>Total units sold by all regions:
        <xsl:value-of select="sum(.//units)"/><br />
        Total sales amounts, all regions:
        <xsl:value-of select="sum(.//amount)"/>
    </p>
</xsl:template>

The result, viewed in Internet Explorer, is:

Quarter beginning: 2001-01
Total units sold by all regions: 1512
Total sales amounts, all regions: 53781.58

floor(num) and ceiling(num)

The number of units sold by the four regions in our sample XML document are 374, 512, 161, and 425. If we wanted to construct a bar graph for these figures in some XML application, such as Scalable Vector Graphics, we may not want to set the Y-axis origin at 0, because it would diminish the (fairly slight) differences among the four regions. For example, in this case, we might want the Y-axis origin to 100—that is, the highest multiple of 100 which is less than or equal to our lowest set of values to be graphed.

Each region's "closest-and-lower multiple of 100" value can be obtained using an XPath expression such as the following:

floor(.//units div 100) * 100

Similarly, the top of the Y axis (for each region) can be established using:

ceiling(.//units div 100) * 100

round(num)

To display the values of the <amount> elements rounded to the nearest integer value, use round().

Example

This example demonstrates the round() function.

XML File (xpathfuncs.xml)

Change the href attribute in xpathfuncs.xml (shown in Sample XML Data File for XPath Functions) to reference round.xsl.

XSLT File (round.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="sales">
    <table border="1">
        <tr>
            <th>Region</th>
            <th>Approx Sales</th>
        </tr>
        <xsl:for-each select="region">
            <tr>
                <td><xsl:value-of select="@name"/></td>
                <td align="right"><xsl:value-of select="round(amount)"/></td>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Region | Approx Sales
Northeast | 12500
Southeast | 17692
Southwest | 8350
Northwest | 15240

Processor Output

<?xml version="1.0" encoding="UTF-16"?><table
border="1"><tr><th>Region</th><th>Approx
Sales</th></tr><tr><td>Northeast</td><td
align="right">12500</td></tr><tr><td>Southeast</td><td
align="right">17692</td></tr><tr><td>Southwest</td><td
align="right">8350</td></tr><tr><td>Northwest</td><td
align="right">15240</td></tr></table>


Using Numeric Operators to Perform Math Operations in XPath

Simple arithmetic operations, such as addition and subtraction, can be used in XPath expressions.

Operator | Description/Example
num1 + num2 | Adds two numbers, returning their sum.
num1 - num2 | Subtracts num2 from num1, returning the difference.
num1 * num2 | Multiplies num1 times num2, returning the product.
num1 div num2 | Divides num1 by num2, returning the quotient. (This is a floating-point division, which means that the value returned may include a fractional part. 10 div 4 equals 2.5, not 2 or 3.)
num1 mod num2 | Returns the modulus—that is, divides num1 by num2, returning the remainder.

Note Division cannot be performed using a simple slash, /, because that character is used as a separator between the steps in a location path. You must use the div operator to represent division.

+ operator

Add the Northeast and Southeast's sales volumes using an XPath expression such as:

units[../@name="Northeast"] + units[../@name="Southeast"]

- operator

You could calculate the total sales amounts of all regions, except the Northwest, using an XPath expression such as the following:

sum(amount) - amount[../@name="Northwest"]

* operator

To calculate the sales tax on a region's sales amount, multiply the tax rate times the amount. For instance:

amount * .07

(assuming a seven-percent sales tax).

div operator

To calculate and display the average number of units sold across all regions in this quarter, you could use an XSLT template rule such as:

<xsl:template match="sales">
    Average units sold for all regions:
    <xsl:value-of select="sum(.//units) div count(.//units)"/>
</xsl:template>

The result, displayed in Internet Explorer, is:

Average units sold for all regions: 378

mod operator

The mod operator is commonly used for enabling a style sheet's template rules to perform a given action every N times, such as doing one thing on an even-numbered table row and something else on an odd-numbered row.

Example

This example uses the mod operator to display the sales figures for each region in alternating bold and normal text.

XML File (xpathfuncs.xml)

Change the href attribute in xpathfuncs.xml (shown in Sample XML Data File for XPath Functions) to reference mod.xsl.

XSLT File (mod.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="sales">
    <table border="1">
        <tr>
            <th>Region</th>
            <th>Approx Sales</th>
            <th>Units</th>
        </tr>
        <xsl:for-each select="region">
            <xsl:choose>
                <xsl:when test="position() mod 2 = 0">
                    <tr>
                        <td><b>
                            <xsl:value-of select="@name"/>
                        </b></td>
                        <td align="right"><b>
                            <xsl:value-of select="round(amount)"/>
                        </b></td>
                        <td align="right"><b>
                            <xsl:value-of select="units"/>
                        </b></td>
                    </tr>
                </xsl:when>
                <xsl:otherwise>
                    <tr>
                        <td>
                            <xsl:value-of select="@name"/>
                        </td>
                        <td align="right">
                            <xsl:value-of select="round(amount)"/>
                        </td>
                        <td align="right">
                            <xsl:value-of select="units"/>
                        </td>
                    </tr>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Region | Approx Sales | Units
Northeast | 12500 | 374
Southeast | 17692 | 512
Southwest | 8350 | 161
Northwest | 15240 | 465

Processor Output

<?xml version="1.0" encoding="UTF-16"?><table
border="1"><tr><th>Region</th><th>Approx
Sales</th><th>Units</th></tr><tr><td>Northeast</td><td
align="right">12500</td><td
align="right">374</td></tr><tr><td><b>Southeast</b></td><td
align="right"><b>17692</b></td><td
align="right"><b>512</b></td></tr><tr><td>Southwest</td><td
align="right">8350</td><td
align="right">161</td></tr><tr><td><b>Northwest</b></td><td
align="right"><b>15240</b></td><td
align="right"><b>465</b></td></tr></table>


Using XSLT Functions in XPath Expressions

The XPath specification defines many functions. XSLT style sheets have several additional functions available to them. These include:

Function | Description
document(obj, ns?) | Allows processing of more than one source document
key(str, obj) | Retrieves a key assigned by the <xsl:key> element
format-number(num, str, str?) | Formats a numeric value in any of a variety of ways
current() | Locates the current node in a node-set
unparsed-entity-uri(str) | Returns the URI of a specified unparsed entity
generate-id(ns?) | Assigns a unique identifier to the first node in a given node-set
system-property(str) | Returns the value of a specified system property, such as the name or version of the XSLT processor

For more information about these functions, including examples, see the following topics in the XSLT Reference:

  • document Function
  • key Function
  • format-number Function
  • current Function
  • unparsed-entity-uri Function
  • generate-id Function
  • 1system-property Function


Sample XML Data File for XPath Functions

Topics and XPath expressions in this section use the following XML file. Note that the name attributes on the <region> elements are declared in the DTD to be of type ID.

To use an XSLT file to display this XML file in Internet Explorer, insert the XSLT filename in the href attribute.

XML File (xpathfuncs.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="myfile.xsl" ?>
<!DOCTYPE sales [
<!ELEMENT sales (region*)>
<!ATTLIST sales quarter CDATA #IMPLIED>
<!ELEMENT region (units, amount)>
<!ATTLIST region name ID #IMPLIED>
<!ELEMENT units (#PCDATA) >
<!ELEMENT amount (#PCDATA) >
]>
<sales quarter="2001-01">
   <region name="Northeast">
      <units>374</units>
      <amount>12500.26</amount>
   </region>
   <region name="Southeast">
      <units>512</units>
      <amount>17692</amount>
   </region>
   <region name="Southwest">
      <units>161</units>
      <amount>8349.72</amount>
   </region>
   <region name="Northwest">
      <units>465</units>
      <amount>15239.6</amount>
   </region>
</sales>


Constructing Complex XPath Searches

Once you have learned the rudiments of XPath syntax, creating a complex search of an XML document's contents is effectively a matter of combining various location steps into a complex location path or combining multiple location paths to form a compound location path.

This section covers the following:

  • 1Constructing an XPath with Axis, Node Test, and Predicate
  • Constructing a Multi-step XPath Expression
  • Constructing a Compound Location Path Using Union

See Also

Introduction to XPath Syntax | Context and Navigation in XPath | Using XPath Axes to Navigate through XML Data | Filtering XML Data Using XPath Predicates


Constructing an XPath with Axis, Node Test, and Predicate

An individual location step in an XPath location path consists of up to three components: an axis, a node test, and a predicate. If all three components are present, the form of a location step is:

axis::nodetest[predicate]

For example:

child::person[attribute::birthdate &lt;= "1951-06-18"]

says to start at the context node, locate all its children named "person", and from among those child nodes select only those with a birthdate attribute which is less than or equal to "1951-06-18".

Note that the predicate portion of this location step itself contains a location step, attribute::birthdate, but that the predicate as a whole does not constitute a location step. For more information, see Differences between XPath Expressions and XSLT Patterns.

Note In the remainder of this topic, we will use the XPath abbreviated syntax for axes and node tests. For instance, with the abbreviated syntax, the above location step can be more concisely represented as:
person[@birthdate &lt;= "1951-06-18"]
For more information, see Using Abbreviations in XPath Expressions.


Constructing a Multi-step XPath Expression

Location paths can contain more than one location step, separated from one another by slashes. Each succeeding location step, reading the pattern from left to right, is evaluated in the context of the nodes selected by all the location steps which precede it.

Consider the following location path:

person[@birthdate &lt;= "1951-06-18"]/surname[substring(., 1, 1)="S"]

This location path consists of two location steps. We have already seen in this section the first step (preceding the slash). It locates a node-set consisting of only one node, or none, or several. If there is at least one node in the resulting node-set, the second step (following the slash) kicks in, and restricts the list of matching nodes even further. Specifically, of the node(s) selected by the first step, the location path as a whole selects only those (if any) with a child named <surname> whose content begins with the letter "S".

Note that the above location path moves you "down" the document tree, from the context node, to its <person> child(ren), to the <surname> child(ren) of each of the matching <person> elements. Because of the wide variety of XPath axes, however, this "downward" direction is not the only option available to you. For example, a location path might be constructed as follows:

person[@birthdate &lt;= "1951-06-18"]/surname[substring(., 1, 1)="S"]/../preceding-sibling::*

The two addition location steps in this path move you from the node(s) selected in the earlier example "up" to their parents (..), and then "sideways" to include only the nodes which are preceding siblings of those parents (preceding-sibling::*).

See Also

Using XPath Axes to Navigate through XML Data | Constructing the Node-Test Portion of a Location Step | Filtering XML Data Using XPath Predicates


Constructing a Compound Location Path Using Union

Simple XPath location paths consist of one or more location steps, any or all of which can be quite complex.

The XPath specification allows an even broader reach through any document, by providing for compound location paths—multiple location paths, separated from one another by a vertical bar or "pipe" symbol, |. The resulting node-set represents the union of all nodes retrieved by all of its constituent location paths.

We see simple examples of compound location paths in the built-in template rules defined by the XSLT specification. For instance:

<xsl:template match="comment() | processing-instruction()" />

matches the set of all nodes in the document which are of either the comment or the processing instruction node types. For more information about the built-in template rules, see How XSLT Template Rules Depend on Context.

Most often, compound location paths are used to simplify locating document content which comes from different branches of the document tree. For example, consider the example XML document shown below.

Although this document is structurally simple, using a single location path to obtain content from different branches of its tree of nodes can be extremely complicated.

You could, for example, locate the <primate> element corresponding to "gibbon", the second <marsupial> element (whatever it is), and all the <insect> elements using a single location path consisting of multiple steps, utilizing various axes such as ancestor::, parent::, preceding-sibling::, and child:: perhaps together with the position() or other functions. Such a location path would be difficult to construct in the first place, difficult to maintain, and quite possibly useless if intervening elements are later added to the document (or existing ones dropped).

It is much simpler to achieve this with a compound location path such as the match pattern in the example XSLT template rule below.

Example

XML File (animals.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="animals.xsl" ?>
<animals>
    <insects>
        <insect>bee</insect>
        <insect>fly</insect>
        <insect>beetle</insect>
        <insect>ant</insect>
    </insects>
    <mammals>
        <marsupials>
            <marsupial>kangaroo</marsupial>
            <marsupial>opossum</marsupial>
        </marsupials>
        <primates>
            <primate>gibbon</primate>
            <primate>lemur</primate>
            <primate>gorilla</primate>
            <primate>chimpanzee</primate>
        </primates>
    </mammals>
</animals>

XSLT File (animals.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="*[.='gibbon'] | marsupial[2] | insect">
    <p><xsl:value-of select="."/></p>
</xsl:template>

</xsl:stylesheet>

Formatted Output

bee
fly
beetle
ant
opossum
gibbon

Processor Output

<?xml version="1.0" encoding="UTF-16"?><p>bee</p><p>fly</p><p>beetle</p><p>ant</p><p>opossum</p><p>gibbon</p>

For more information about the position() function, see Processing Node-Sets by Using Node-Set Functions.


Useful Patterns for XPath Expressions

This section covers the following:

  • Useful Patterns for XPath Wildcards and Axes
  • Useful Boolean Predicates in XPath Expressions
  • Common Use of Predicate Filtering in XPath Expressions


Useful Patterns for XPath Wildcards and Axes

Try to select an efficient approach. The use of axes and wildcard characters can radically simplify your code, but that come at the expense of decreased efficiency. For example, the pattern "//*" will match every node in the tree, which is useful if you're trying to search for a given element or attribute but which can be disastrous if your XML structure has 100,000 nodes.

//* Linearizes Tree

The //* pattern will put all of the nodes in a tree into a single nodeset in regular traversal order.

//* Is Least Efficient

Using universal match for searches is the least efficient way of finding nodes, as it traverses every point in the tree.

.//*[@attrName] Gets Elements With a Specific Attribute

The id() function has been removed from the XSLT specification, but you can search for all elements with given attributes with the XPath expression //*[@id='myID'].

ancestor-or-self::* Gets Ancestor List

This pattern can be used to retrieve a list of all direct ancestors of a given node, useful for identifying paths.

Use Axes and Wildcards for Recursion

Both Axes and Wildcards are perfect for making recursive calls.

following-sibling::* is a node set

This pattern returns ALL sibling nodes after the current node. To get the next node, use:

following::sibling::*[1]


Useful Boolean Predicates in XPath Expressions

A predicate expression (that is, an XPath expression within square brackets) takes the current context and applies a test to it. If the test fails for the context, then it is eliminated from the node-set that the context belongs to, otherwise it stays in. You can use this technique for performing very fine grain analysis of the XML tree.

Predicates return booleans

For each node, predicates return either true or false, indicating that the given node either satisfies or doesn't satisfy the predicate. Numeric expressions will always evaluate to true unless the result is 0, while an empty string is considered to be a false value within a predicate.

Use OR for conjoining: [a or b]

will match either a or b.

Use AND for filtering: [a and b]

will match only if both a and b nodes exist.

Multiple predicates

You can have a predicate filter of the form path[A][B], or path1[A]/path2[B]. XPath expressions work from left to right, so that with the expression path1[A]/path2[B], path1[A] will be determined first and only those elements that remain have path2[B] applied.

AND is faster than sequential predicates

The MSXML3 parser can handle Boolean evaluations faster than it can node-set creation or reduction. As a consequence, while both path[A][B] and path[A and B] will generate the same results, the use of 'and' will improve the performance of your XPath query significantly.

AND short-circuits expressions

One reason for the efficiency when using AND is that if the first part of an intersection (an AND clause) is false, the second part will not be evaluated. As a consequence, when building AND XPath expressions, place the most efficient clause first to cut down on the number of searches, especially if one clause is especially complex. For example, the following XPath expression selects all elements that have the same name as the parameter $price.type before applying the filtering algorithm to make sure the price is in between the low and high price:

//*[name(.)=$price.type and (number(.) &gt; $price.low and number(.) &lt; $price.high)]


Common Use of Predicate Filtering in XPath Expressions

There are a number of predicate functions, but you can use a few fairly simple XPath expressions to get surprisingly sophisticated results.

The following expression matches a given element by name without having to specify the name explicitly. Useful for parameterization.

*[name(.)='myName'] or *[name(.)=$myNameVar]

The following expression returns even elements only. Useful for creating alternating schemes.

*[position() mod 2 = 0]

The following expression matches all elements in the tree for which the id attribute corresponds to the idref attribute of the current node. This is useful when you have multiple types of information in an XML document (such as employees and offices), and need to relate one to the other.

//*[@id=./@idref]


Data-Driven Transformations

With Template-Driven Transformations, the output template (the overall layout of the XSLT file) drives the transformation process, pulling in data from the XML tree and inserting it into the overall template. This works well when the data has a fairly simple and homogeneous structure. If you know what the output structure should be, use the template-driven model.

XSL Transformations (XSLT) also provide mechanisms for data-driven transformations, in which the output is assembled from template fragments based on the structure of the input document. This is especially useful for XML that represents complex data structures or documents, as described in Handling Irregular Data Hierarchies. If you only know what types of elements you might be encountering in the XML source, but not their order, parentage, or relationship to other elements, use the data-driven model.

This section covers the following:

  • Handling Irregular Data Hierarchies
  • Defining Match Patterns in <xsl:template>
  • Debugging a Style Sheet
  • Using the Built-in Template Rules
  • Creating a Table of Contents
  • Translating from One XML Schema to Another
  • Generating Comments, Processing Instructions, and Elements
  • Generating Elements without Prefixes


Handling Irregular Data Hierarchies

One of the benefits of using XML is the ability to model irregular data hierarchies, including data with the following characteristics.

  • Collections of heterogeneous elements
  • Structures with many optional elements
  • Structures where the order is important
  • Recursive structures
  • Structures with complex containment requirements

Most of these conditions are present in XML that represents documents.

The pole.xml example below contains heterogeneous collections of elements; a section can contain an arbitrary collection of <title> elements, <p> elements, <list> elements, and so on. Many elements are indeed optional—a section need not contain <p> or <list> elements, or other "section" elements. The order of most elements is important to preserve in the output—the first section comes before the second section. The structure is recursive because a "section" element can contain another "section". The <emph> element is probably allowed anywhere—indicating a complex set of containment requirements.

The ability to handle such irregular and recursive data makes XSL Transformations (XSLT) useful for transforming documents into a display language such as HTML—hence the name and origins of the Extensible Stylesheet Language (XSL).

The mechanism for handling data-driven transformations is similar to subroutines in programming languages. Template fragments (subroutines) can be defined and called. Instead of calling the templates by name, however, the most appropriate fragment is chosen based on the type of element for which the template is designed.

First, here is a simple introductory example that is template-driven:

<xsl:template match="/">
<html>
   <body>
   <xsl:apply-templates/>
   </body></html></xsl:apply-templates>

Then pick an element from the XML document, such as <title>. Think of how you want the <title> tags to look in HTML. For example, <h1>title text</h1>. Then write this in XSLT syntax:

<xsl:template match="title">
   <h1><xsl:value-of select="text()"/></h1>
</xsl:template>

This shows the title text as <h1> in the browser, but we have not explicitly said where we want the title placed. It just fell in because of the processing model of XSLT. This is the distinction between template-driven and data-driven XSLT files.

As another example, to manage the XML data, write an output template for the HTML "wrapper," which inserts the document title into the output in two places, and then asks XSLT to find the appropriate template for "section" elements. For example:

<xsl:template match="/">
  <html>
    <head>
      <title><xsl:value-of select="document/title"/></title>
    </head>
    <body>
      <h1><xsl:value-of select="document/title"/></h1>
      <xsl:apply-templates select="document/section"/>
    </body>
  </html>
</xsl:template>

The top-level template (or root template) must be identified as such by placing it within a template and giving it the special pattern / to indicate that this is the template for the document root.

The <xsl:apply-templates> element selects the "section" children of the document (not all of them, just the top level) and asks XSLT to find and apply an appropriate template. Now it is necessary to write a template rule that is appropriate for "section" elements:

<xsl:template match="section">
  <div>
    <xsl:apply-templates />
  </div>
</xsl:template>

The XSLT processor will output this template fragment for each of the "section" elements selected by the <xsl:apply-templates> element. The value of the match attribute indicates the kinds of nodes for which this template is appropriate. In this case, it indicates that this template is appropriate for "section" elements. The nodes selected by <xsl:apply-templates> are matched up with the correct template.

The template for sections itself contains an <xsl:apply-templates> element. Without a select attribute, all the children will be selected, and the XSLT processor will take each one in order (title, p, list, section) and look for an appropriate template. There already is a section template—this one—and the XSLT processor will recursively apply it, resulting in a nested structure of <div> elements that mirrors the nested structure of <section> elements in the source document.

Now define some more templates to handle other element types.

<xsl:template match="title">
  <h2><xsl:apply-templates /></h2>
</xsl:template>

<xsl:template match="p">
  <p><xsl:apply-templates /></p>
</xsl:template>

<xsl:template match="list">
  <ul>
    <xsl:for-each select="item">
      <li><xsl:apply-templates /></li>
    </xsl:for-each>
  </ul>
</xsl:template>

<xsl:template match="emph">
  <i><xsl:apply-templates /></i>
</xsl:template>

In each case, you can include <xsl:apply-templates> to continue selecting the children (whatever they may be) and finding the appropriate template.

The <xsl:apply-templates> element is not limited to selecting element children, but can select other child nodes as well, including text. You can add a template to copy text children to the output:

<xsl:template match="text()">
   <xsl:value-of select='.' />
</xsl:template>

By recursively processing the source document with <xsl:apply-templates>, this style sheet essentially converts the element types in the source XML to HTML element types. Even in this simple example, you can already see some additional structural modifications occurring, notably the creation of the <head> element and the duplication of the document title in both the <h1> element and the <title> element.

This collection of templates can be packaged into a style sheet file by placing them within an <xsl:stylesheet> element, as shown in the preliminary example below. The XSLT namespace must be declared before the first template rule.

The above template rules are demonstrated in the following example:

  • Example of Transforming Irregular Data Hierarchies


Example of Transforming Irregular Data Hierarchies

This example illustrates the data-driven model of XSLT processing in which you can create isolated templates for the types of nodes you expect to see in the output without too much consideration of their structure. In places where the structure is locally known, you can use <xsl:for-each> and <xsl:value-of> to populate the template. For example, "list" and "item" elements appear in a regular and predictable structure. The ability to switch smoothly between data-driven and template-driven transformation is an important feature of XSLT.

XML File (pole.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="poleeasy.xsl"?>
<document>
  <title>To the Pole and Back</title>
  <section>
    <title>The First Day</title>
    <p>It was the <emph>best</emph> of days, it was the
      <emph>worst</emph> of days.</p>
    <list>
      <item><emph>best</emph> in that the sun was out.</item>
      <item><emph>worst</emph> in that it was 39 degrees below zero.</item>
    </list>
    <section>
      <title>Lunch Menu</title>
      <list>
        <item>ice cream</item>
        <item>popsicles</item>
      </list>
    </section>
  </section>
  <section>
    <title>The Second Day</title>
    <p>Ditto the first day.</p>
  </section></document>

XSLT File (poleeasy.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
    <head>
      <title><xsl:value-of select="document/title"/></title>
    </head>
    <body>
      <h1><xsl:value-of select="document/title"/></h1>
      <xsl:apply-templates select="document/section"/>
    </body>
  </html>
</xsl:template>

<xsl:template match="section">
  <div>
    <h2><xsl:value-of select="title"/></h2>
    <xsl:apply-templates />
  </div>
</xsl:template>

<xsl:template match="p">
  <p><xsl:apply-templates /></p>
</xsl:template>

<xsl:template match="list">
  <ul>
    <xsl:for-each select="item">
      <li><xsl:apply-templates /></li>
    </xsl:for-each>
  </ul>
</xsl:template>

<xsl:template match="emph">
  <i><xsl:apply-templates /></i>
</xsl:template>

<xsl:template match="text()">
   <xsl:value-of select="."/>
</xsl:template>

<xsl:template match="title"/>

</xsl:stylesheet>

Formatted Output

Processor Output

White space adjusted for clarity.

<html>
<head>
<title>To the Pole and Back</title>
</head>
<body>
<h1>To the Pole and Back</h1>
<div>
   <h2>The First Day</h2>
   <p>It was the <i>best</i> of days, it was the <i>worst</i> of days.</p>
   <ul>
      <li><i>best</i> in that the sun was out.</li>
      <li><i>worst</i> in that it was 39 degrees below zero.</li>
   </ul>
   <div>
      <h2>Lunch Menu</h2>
      <ul>
         <li>ice cream</li>
         <li>popsicles</li>
      </ul>
   </div>
</div>
<div>
   <h2>The Second Day</h2>
   <p>Ditto the first day.</p>
</div>
</body>
</html>


Defining Match Patterns in <xsl:template>

The match attribute on the <xsl:template> element contains a pattern expression. The syntax is the same as that used to select nodes with <xsl:for-each>, <xsl:value-of>, and <xsl:apply-templates> elements. However, the pattern is used in quite a different way.

In a "select" pattern, the pattern describes a query down from a particular node to locate a new set of nodes. A "match" pattern is quite different. The match pattern does not locate anything new, but rather compares a specific node against a pattern to see if the node matches that pattern, and thus whether or not to use a particular template.

Here are some of the differences between the use of match patterns and select patterns.

Select patterns | Match patterns
Starts with a node (the context), and identifies more nodes. | Starts with a node (the target), and yields a true/false match/didn't match result.
Starts at the context and drills down into the data. | Starts by testing the node against the node target, and then checks the context, including ancestry and descendants.
Represents a query into an XML document. | Represents a pattern of contextual information against which a particular node can be tested. Match patterns are quite similar to selectors in cascading style sheets (CSS).

The simplest match pattern is just a single element name, such as "section," or node type, such as "text()." If a text node matches the "text()" pattern, the associated template will be used; if a "section" element matches the "section" pattern, the associated template will be used.

Matches become more complex when they are used not only to test a node, but also the context in which the node appears in the source document. The pattern "section/title" will match "title" elements that are children of "section" elements. "title" elements not within a section (for example, the document title) do not match this pattern, and a separate template must be defined (such as "document/title"). The target of the pattern (the rightmost term) represents the node to be tested, in a way similar to a "select" pattern in which the target represents the nodes to select.

The following table lists some match patterns and their meanings.

Pattern | Meaning when used as a match pattern
title | Matches "title" elements.
section/title | Matches "title" elements that are children of "section" elements.
section//title | Matches "title" elements contained within "section" elements.
section/title[@short-name] | Matches "title" elements that are children of "section" elements, and that have a "short-name" attribute.
appendix//section[@type='reference']/title | Matches "title" elements that are children of "section" elements. The section must also have a "type" attribute with the value "reference", and have an "appendix" ancestor.
appendix[.//section[@type='reference']/title] | Matches "appendix" elements that contain "section" descendants, which, in turn, have both a "type" attribute with the value "reference" and a "title" child.

For more information, see Introduction to XPath Syntax and XPath Syntax.

You can add another template to the Pole sample to provide different formatting (H3 instead of H2) for sections when they appear in the context of another section. For example:

<xsl:template match="section">
  <div>
    <h2><xsl:value-of select="title"/></h2>
    <xsl:apply-templates />
  </div>
</xsl:template>

<xsl:template match="section/section">
  <div>
    <h3><xsl:value-of select="title"/></h3>
    <xsl:apply-templates />
  </div>
</xsl:template>

Notice that a section within a section will match the pattern "section" as well as the "section/section" pattern. Which template will be selected? The rule is: Templates later in the style sheet override earlier templates. To ensure that the XSL Transformations (XSLT) processor checks the "section/section" pattern first, place it farther down in the style sheet. Most of the templates in this sample are mutually exclusive, so their order is unimportant.

Try it! Download the full To The Pole sample at XSLT Developer's Guide Samples.


Debugging a Style Sheet

Because the interaction of a style sheet with a data file can be complex, and style sheet errors are not always obvious, this section provides troubleshooting advice for the style sheet author.

Developing in the browser can be difficult because the error can be in so many places and can be hidden by the browser. You can use a script at the command prompt, or run the MSXSL command prompt utility, to see error messages. For more information, see XSLT Utilities and Samples You Can Download.

Problem:

No output is produced.

Solution:

When browsing to an XML file with an XSL Transformations (XSLT) style sheet, well-formedness errors in the source file or the style sheet are reported, along with XSLT syntax errors and run-time errors. These errors are not automatically reported when using XSLT from script or on data islands. For sample code to detect, format, and report these errors, see Performing Error Handling with XSLT. Alternatively, use direct browsing as a development tool for reporting errors. For more information, see Using the Default Style Sheet.

If no errors are reported, the problem is most likely an error in the style sheet design, which can be diagnosed and corrected by the style sheet author. Begin by testing that the root template of the style sheet is being executed, using the method outlined in the following section.

Problem:

The expected template is not being used.

Solution:

If the contents of a template, including the root template, are not appearing in the output, check to see if the template is being called by adding an explicit trace message.

<xsl:template match="address">
  !! inside address template !!
  <xsl:apply-templates select="zipcode"/>
</xsl:template>

If the trace message appears in the output, the template is being executed, and the problem is likely that this <xsl:apply-templates> is not returning anything. For more information about why the select pattern returns no results, see the section that follows, "No Results from Select Pattern."

If the trace message does not appear, the problem could be that the match pattern is in error. Check the spelling and case of element and attribute names, and check that the full context for the match is actually present in the source data.

Also determine which <xsl:apply-templates> element should invoke the template and ensure that it is selecting the correct nodes. For more information, see "No Results from Select Pattern".

If the template uses the root pattern (/) and is not being called, check that no template later in the style sheet uses the root pattern or omits the match attribute (matching all nodes, including the document root). If the style sheet is being executed against a node other than the document root, a template matching that element is used instead of the root template.

Problem:

No results are generated from the Select pattern.

Solution:

One of the most frequent errors preventing output is select patterns that don't match the input data. Fortunately these are easy to fix. The debug line added to the example below uses <xsl:value-of> to output the node and its children as preformatted XML source.

<xsl:template match="address">
  <pre><xsl:value-of select="."/></pre>
  <xsl:apply-templates select="zipcode"/>
</xsl:template>

When comparing the actual XML data to the select pattern, you may find spelling mistakes in element and attribute names; for example, the data could show "zip-code" or "zipCode" as the correct element name. The context of the query can be checked—is "zipcode" a child of "address"? And the source data can also be checked for accuracy—does this "address" have a "zipcode"?

For complex patterns, it is often helpful to progressively simplify the pattern to isolate the problem.

Problem:

Elements with the XSLT namespace appear in the output.

Solution:

Elements from the XSLT namespace appearing in the output indicate that the XSLT namespace declaration is using an incorrect URL. The XSLT processor doesn't recognize these elements as XSLT elements and treats them as output elements.

The correct namespace identifier for XSLT is "http://www.w3.org/1999/XSL/Transform".

Problem:

Need to highlight the elements which are not handled by a template.

Solution:

Often it is helpful to author a style sheet incrementally, adding templates for elements one at a time. Adding this template to your style sheet will show you visually those elements that do not yet have templates associated with them.

<xsl:template match="*">
  <span style="background-color:yellow">
    <xsl:attribute name="title">&lt;<xsl:value-of select="."/>&gt;</xsl:attribute>
    <xsl:apply-templates/>
  </span>
</xsl:template>

Add this template near the top of your style sheet so that it does not override templates that handle specific elements. This template will display a yellow background behind the content of any element without a specific template in existence. Running the mouse over the yellow areas will display a ToolTip showing those elements that must still be handled by templates.

See Also

Displaying Transformation Results | Using the Default Style Sheet | Debugging XSLT


Using the Built-in Template Rules

The November 1999 XSL Transformations (XSLT) Recommendation includes two built-in templates, which are included in the Microsoft® XSLT processor. These templates make it easier to create style sheets for irregular data by passing text from the source document to the output automatically.

The built-in template included in the Microsoft XSLT processor for element nodes and the root node looks like this:

<xsl:template match="/|*">
   <xsl:apply-templates/>
</xsl:template>

The built-in template for text and attribute nodes is as follows:

<xsl:template match="text()">
   <xsl:value-of select="."/>
</xsl:template>

The built-in template for processing instructions and comments does nothing, as follows:

<xsl:template match="processing-instruction()|comment()"/>

On their own, these templates provide for a complete, though simple, transformation of the source document. Elements and the document root are traversed, although they do not generate any output themselves. The values of text nodes and CDATA sections are passed through. Comments and processing instructions are not processed and thus do not appear in the output. The end result is that these templates by themselves strip all markup from the source document but preserve the text.

To override these built-in templates, specify your own templates in the style sheet so that every node is handled.


Creating a Table of Contents

Often an element from the source XML document appears multiple times in the output, with different formatting in each case. The classic example is the table of contents, in which section titles appear at the start of the document, and each one is also displayed at the start of the section. XSL Transformations (XSLT) makes it easy to place something in multiple places—just select it multiple times using the <xsl:for-each> or <xsl:apply-templates> elements.

The <xsl:for-each> element provides a simple way to apply different formatting for each location. The <xsl:for-each> element contains its own template, so different output for various occurrences of an element is implied. In the following example, the "title" elements are pulled from the top-level section and used in a simple table of contents.

<xsl:template match="/">
  <h4>Table of Contents</h4>
  <xsl:for-each select="document/section">
    <div style="margin-left:1em">
      <xsl:value-of select="title"/>
    </div>
  </xsl:for-each>
  <xsl:apply-templates select="document/section"/>
</xsl:template>

<xsl:template match="section">
  <div>
    <h2><xsl:value-of select="title"/></h2>
    <xsl:apply-templates />
  </div>
</xsl:template>

This example is a simplification of the final version of the To The Pole Sample, which has a hyperlinked table of contents.

Try it! Download the full To The Pole sample at XSLT Developer's Guide Samples. Note: the sample uses XSL rather than XSLT.

Often, however, a hierarchical table of contents is needed, typically when the document itself defines sections recursively—sections containing subsections ad infinitum. <xsl:apply-templates> is suited for recursive structure, and allows templates to be defined locally. A template scoped in this way will not participate in the selection of an appropriate template at the global level. The template will only apply for items placed in the table of contents.

A document grammar with recursive structure is used by the Worldwide Web Consortium (W3C) for XML versions of recommendations, such as the XSLT Transformation. This grammar contains nested sections named "div1", "div2", and so on.

The following example shows a hierarchical table of contents for this grammar. It uses an <xsl:template> element contained in (scoped to) the <xsl:apply-templates> element, which selects the top-level sections ("div1" in the document body).

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template match="text()"/>

<xsl:template match="/">
  <html>
    <body>
      <H3>Table of Contents</H3>
      <xsl:apply-templates select="spec/body/div1 | spec/back/*" mode="toc"/>
    </body>
  </html>
</xsl:template>

<xsl:template match="div1|div2|div3|div4|div5|div6" mode="toc">
  <div style="margin-left:1em"><xsl:number level="multiple" format="1.1.1.1.1. " count="div1|div2|div3|div4|div5|div6"/>
  <xsl:value-of select="head"/><br/>
  <xsl:apply-templates select="div2|div3|div4|div5|div6" mode="toc"/>
  </div>
</xsl:template>

<xsl:template match="inform-div1" mode="toc">
  <div style="margin-left:1em"><xsl:number level="multiple" format="1.1.1.1.1. "/>
    <xsl:value-of select="head"/> (Non-Normative)
    <xsl:apply-templates select="div2" mode="toc"/>
  </div>
</xsl:template>

</xsl:stylesheet>

The local templates are tested for a match before looking for a global template, and build nested <DIV> elements to indent each level in relation to its parent. Because <xsl:apply-templates> is careful to select only elements that can be matched by local templates, there is no possibility of interfering with the operation of other templates in the style sheet.

Try it! Download the full version of the preceding example, XSLT Recommendation Table of Contents, at XSLT Developer's Guide Samples.


Translating from One XML Schema to Another

An XSLT file can translate data from one XML grammar to another. The mechanisms in XSLT can be applied directly to any XML grammar. Templates can be created using elements from the output grammar and populated using elements such as <xsl:for-each> and <xsl:value-of>.

Suppose that you receive stock quotes in the following format:

<?xml version="1.0"?>
<investments>
  <item type="stock" exch="nyse"   symbol="ZCXM" company="zacx corp"
        price="28.875"/>
  <item type="stock" exch="nasdaq" symbol="ZFFX" company="zaffymat inc"
        price="92.250"/>
  <item type="stock" exch="nasdaq" symbol="ZYSZ" company="zysmergy inc"
        price="20.313"/></investments>

You want to add this information to the rest of your stock information, which uses a different schema. You would like this information to look like this.

<?xml version="1.0"?>
<portfolio xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <stock exchange="nyse">
    <name>zacx corp</name>
    <symbol>ZCXM</symbol>
    <price dt:dt="number">28.875</price>
  </stock>
  <stock exchange="nasdaq">
    <name>zaffymat inc</name>
    <symbol>ZFFX</symbol>
    <price dt:dt="number">92.250</price>
  </stock>
  <stock exchange="nasdaq">
    <name>zysmergy inc</name>
    <symbol>ZYSZ</symbol>
    <price dt:dt="number">20.313</price>
  </stock>
</portfolio>

To transform the "investments" data into the "portfolio" grammar, you can use familiar XSLT techniques. Your templates will contain output elements such as "stock" instead of HTML elements. Attribute values are extracted using <xsl:value-of> and either generate new attributes using <xsl:attribute> or are converted to elements.

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="/">
  <portfolio xmlns:dt="urn:schemas-microsoft-com:datatypes">
    <xsl:for-each select="investments/item[@type='stock']">
      <stock>
        <xsl:attribute name="exchange"><xsl:value-of select="@exch"/></xsl:attribute>
        <name><xsl:value-of select="@company"/></name>
        <symbol><xsl:value-of select="@symbol"/></symbol>
        <price dt:dt="number"><xsl:value-of select="@price"/></price>
      </stock>
    </xsl:for-each>
  </portfolio>
</xsl:template>

</xsl:stylesheet>

This example also shows XSLT generating a document that declares a namespace. The data types namespace declaration on the <portfolio> element is treated by XSLT like any other attribute appearing on an output element and passed through. In this case, the XSLT namespace declaration is passed through as well.

The translation can be performed in reverse with a similar style sheet, converting "portfolio" data to the "investments" grammar.

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <investments>
    <xsl:for-each select="portfolio/stock">
      <item type="stock">
        <xsl:attribute name="exch"><xsl:value-of select="@exchange"/></xsl:attribute>
        <xsl:attribute name="symbol"><xsl:value-of select="symbol"/></xsl:attribute>
        <xsl:attribute name="company"><xsl:value-of select="name"/></xsl:attribute>
        <xsl:attribute name="price"><xsl:value-of select="price"/></xsl:attribute>
      </item>
    </xsl:for-each>
  </investments>
</xsl:template>

</xsl:stylesheet>

Note the use of <xsl:attribute> to not only copy an attribute value to a new attribute, but also to convert element content to attribute values.

Try it! Download the full version of the Portfolio sample at XSLT Developer's Guide Samples.


Generating Comments, Processing Instructions, and Elements

When generating XML, it is often useful to generate comments, processing instructions, and elements that are named programmatically. XSLT provides a set of commands for creating specific kinds of nodes in the output. Just as the <xsl:attribute> element can insert an attribute into the tree, XSLT provides a similar set of elements for inserting other types of nodes. For more information about the <xsl:attribute> element, see Selecting and Outputting Attributes.

The <xsl:comment> element inserts a comment into the output. Comments within the style sheet are not passed through to the output, but are treated as comments upon the style sheet itself. When a comment is required in the output, place the comment text within an <xsl:comment> element.

The <xsl:processing-instruction> element allows processing instructions to be inserted into the output. The name attribute specifies the name of the attribute, and the content of the element becomes the text of the processing instruction.

The <xsl:element> element provides an alternative mechanism for creating elements in the output. The name attribute specifies the name of the element. The following two ways of creating a <DIV> element produce identical results.

1) <DIV class="menuItem">
     Choose me
   </DIV>
2) <xsl:element name="DIV">
     <xsl:attribute name="class">menuItem</xsl:attribute>
     Choose me
   </xsl:element>

Attributes must be added to elements created using the <xsl:element> element with the <xsl:attribute> element instead of being placed directly on the element.

Because XSLT allows output elements to be specified directly, there are only a few situations where <xsl:element> is useful, for example, as an escaping mechanism for creating XSLT elements in the output, which allows style sheets to generate style sheets.

Example

The following example converts style sheets to use the <xsl:element> syntax. It uses <xsl:element> to generate elements in the XSLT namespace and inserts processing instructions and a comment at the start of the file.

This style sheet has five template rules.

  • The first adds a boilerplate to the root of the output document, and selects all comments and the document element for copying to the output.
  • The second template copies comments, processing instructions, and text nodes to the output.
  • The third template converts elements to the <xsl:element> syntax.
  • The fourth template converts attributes to the <xsl:attribute> syntax.
  • The fifth template ensures that any elements from the XSLT namespace are copied to the output with their attributes and not converted by the third template.

XSLT File (convert.xsl)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/">
  <xsl:processing-instruction name="xml-stylesheet">type="text/xsl"
 href="style.xsl"</xsl:processing-instruction>
  <xsl:comment>Style sheet converted automatically to
&lt;xsl:element&gt; syntax</xsl:comment>
  <xsl:apply-templates select="comment()"/>
  <xsl:apply-templates select="*"/>
</xsl:template>

<!-- Copy text, comments and processing instructions -->
<xsl:template match="comment() | processing-instruction() | text()">
  <xsl:copy>
    <xsl:apply-templates />
  </xsl:copy>
</xsl:template>

<!-- Convert non-XSL elements to <xsl:element> syntax -->
<xsl:template match="*">
  <xsl:element name="xsl:element">
    <xsl:attribute name="name"><xsl:value-of select="name(.)"/></xsl:attribute>
    <xsl:apply-templates select="@*"/> <!-- consolidate -->
    <xsl:apply-templates select="node()"/>
  </xsl:element>
</xsl:template>

<!-- Convert non-XSL attribute to <xsl:attribute> syntax -->
<xsl:template match="@*">
  <xsl:element name="xsl:attribute">
    <xsl:attribute name="name"><xsl:value-of select="name(.)"/></xsl:attribute>
    <xsl:value-of select="."/>
  </xsl:element>
</xsl:template>

<!-- Copy namespace attributes -->
<xsl:template match="@xmlns:*">
  <xsl:copy><xsl:value-of select="."/></xsl:copy>
</xsl:template>

<!-- Copy XSL elements and their attributes -->
<xsl:template match="xsl:*">
  <xsl:copy>
    <xsl:for-each select="@*">
      <xsl:copy><xsl:value-of select="."/></xsl:copy>
    </xsl:for-each>
    <xsl:apply-templates select="node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Try it! You can download the full version of the Style Sheet Converter in the Portfolio sample at XSLT Developer's Guide Samples.


Generating Elements without Prefixes

You can use <xsl:element> to generate elements when the default namespace of the style sheet is set to XSL. Some style sheets, such as the following one, consist of nearly all elements from the XSL namespace and contain virtually no output elements. It might be convenient to set the default namespace of the document to the XSL namespace so that prefixes can be omitted. <xsl:element> can be used for the rare output elements. Style sheets written in this way are more readable and compact, and more amenable to validation with a document type definition (DTD) or XML Schema.

Example

This example uses just one named output element, "security," so it is easier to use the XSL namespace as the default, and use the <xsl:element> element for this one output element. However, consistently using the "xsl" prefix helps make your style sheets look familiar to other authors.

To view this example, view the HTML file in Internet Explorer.

XML File (portfolio.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="portfolio.xsl"?>
<portfolio xmlns:dt="urn:schemas-microsoft-com:datatypes" xml:space="preserve">
  <stock exchange="nyse">
    <name>zacx corp</name>
    <symbol>ZCXM</symbol>
    <price dt:dt="number">28.875</price>
  </stock>
  <stock exchange="nasdaq">
    <name>zaffymat inc</name>
    <symbol>ZFFX</symbol>
    <price dt:dt="number">92.250</price>
  </stock>
  <stock exchange="nasdaq">
    <name>zysmergy inc</name>
    <symbol>ZYSZ</symbol>
    <price dt:dt="number">20.313</price>
  </stock>
</portfolio>

XSLT File (rename.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns="http://www.w3.org/1999/XSL/Transform">

<!-- Identity transformation template -->
<template>
  <copy>
    <apply-templates select="@* | * | comment() | processing-instruction() | text()"/>
  </copy>
</template>

<!-- Rename "stock" elements to "security" -->
<template match="stock">
  <element name="security">
    <apply-templates select="@* | * | comment() | processing-instruction() | text()"/>
  </element>
</template>

</stylesheet>

HTML File (rename.htm)

Use Interactive HTML File to Rename Elements (rename.htm).


Interactive HTML File to Rename Elements (rename.htm)

HTML File (rename.htm)

<HTML>

<HEAD>
  <TITLE>Filtering and Sorting</TITLE>
  <STYLE>
    BODY { font: bold 12pt Verdana }
    PRE { font: 9pt Verdana }
  </STYLE>
<!--TOOLBAR_START-->
<!--TOOLBAR_EXEMPT-->
<!--TOOLBAR_END--></HEAD>

<XML id="portfolio"   src="portfolio.xml"></XML>
<XML id="renamer" src="rename.xsl"></XML>

<SCRIPT language="JavaScript">
  function rename()
  {
    cell2.innerText = portfolio.documentElement.transformNode(renamer.XMLDocument);
  }</SCRIPT>

<SCRIPT language="JavaScript" for="window" event="onload">
  cell1.innerText = portfolio.documentElement.xml;
  </SCRIPT>

<BODY>

  <P>Source file "investments.xml"</P>
  <PRE id="cell1"></PRE>
  <P>Click on the links below to rename "stock" elements to "security".</P>
  <UL>
    <LI><A href="javascript:rename()">
      Rename</A></LI>
  </UL>
  <PRE id="cell2"></PRE>
    </BODY>
</HTML>


Using XSLT Variables and Parameters

In most programming or scripting languages, Extensible Stylesheet Language Transformations (XSLT) allows the use of constants and variables within style sheets. Constants and variables are respectively called, variables and parameters. This topic covers the use of variables and parameters.

This section covers the following:

  • Using Variables to Store Values that Do Not Change
  • Using Parameters to Store Values that Change
  • Considerations when Using Variables and Parameters

This section includes the following examples:

  • Initial XSLT Example Using Variables
  • Finished XSLT Example Using Variables


Initial XSLT Example Using Variables

The following is the weatherlog.xsl XSLT style sheet.

Example

XML File (weatherlog.xml)

The following XML file records common weather readings in a number of locations over a period of time.

<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="weatherlogv1.xsl"?>
<weather temp_scale="F">
    <day date="2000-11-01">
        <locale place="location1">
            <temp>
            <low>47</low>
            <high>62</high>
         </temp>
         <wind_dir>NNE</wind_dir>
         <wind_speed units="mph">5</wind_speed>
         <barom units="mb">1013.2</barom>
         <rel_humid>.74</rel_humid>
         <precip units="in">0</precip>
      </locale>
      <locale place="location2">
         <temp>
            <low>50</low>
            <high>64</high>
         </temp>
         <wind_dir>NNE</wind_dir>
         <wind_speed units="mph">4</wind_speed>
         <barom units="mb">1015.7</barom>
         <rel_humid>.70</rel_humid>
         <precip units="in">0</precip>
      </locale>
      <locale place="location3">
         <temp>
            <low>48</low>
            <high>61</high>
         </temp>
         <wind_dir>NNE</wind_dir>
         <wind_speed units="mph">8</wind_speed>
         <barom units="mb">1010.0</barom>
         <rel_humid>.68</rel_humid>
         <precip units="in">.1</precip>
      </locale>
   </day>
   <day date="2000-11-02">
      <locale place="location1">
         <temp>
            <low>43</low>
            <high>58</high>
         </temp>
         <wind_dir>NE</wind_dir>
         <wind_speed units="mph">1</wind_speed>
         <barom units="mb">1009.1</barom>
         <rel_humid>.80</rel_humid>
         <precip units="in">2.3</precip>
      </locale>
      <locale place="location3">
         <temp>
            <low>40</low>
            <high>61</high>
         </temp>
         <wind_dir>N</wind_dir>
         <wind_speed units="mph">12</wind_speed>
         <barom units="mb">1011.0</barom>
         <rel_humid>.73</rel_humid>
         <precip units="in">2.0</precip>
      </locale>
   </day>
</weather>

XSLT File (weatherlogv1.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/TR/REC-html40">

<xsl:template match="/">
   <html>
      <head>
         <title>Weather Readings</title>
      </head>
      <body>
         <xsl:apply-templates/>
      </body>
   </html>
</xsl:template>

<!-- Override built-in template rule for text nodes -->
<xsl:template match="text()"/>

<xsl:template match="weather">
   <h1>Weather Readings</h1>
   <xsl:for-each select="day">
      <h2>As of <xsl:value-of select="@date"/></h2>
      <xsl:for-each select="locale">
         <h3><xsl:value-of select="@place"/></h3>
      </xsl:for-each>
   </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Formatted Output

The resulting table shows the date and the locations where readings were taken.

Processor Output

Line breaks added for clarity.

<?xml version="1.0" encoding="UTF-16"?>
<html xmlns="http://www.w3.org/TR/REC-html40">
<head><title>Weather Readings</title></head>
<body>
<h1>Weather Readings</h1>
<h2>As of 2000-11-01</h2>
<h3>location1</h3>
<h3>location2</h3>
<h3>location3</h3>
<h2>As of 2000-11-02</h2>
<h3>location1</h3>
<h3>location3</h3>
</body></html>

See Also

Finished XSLT Example Using Variables


Using Variables to Store Values that Do Not Change

In XSLT, variables are the same as constants in programming and scripting languages. Variables identify generically named objects, from which a specific value can be retrieved.

Unlike programming and scripting constants, the value of an XSLT variable is generally unknown at run time. Some condition in the XML source document, or in the style sheet, can cause the variable's value to be set. Since these conditions can change from one transformation to the next, these objects are known as variables rather than constants.

The <xsl:variable> element is the element that sets a variable's value. Before using this element, you can use a sample XML document to think of situations where variables are useful.

This section covers the following:

  • Using Variables as Convenience Constants
  • Shortening XPath Expressions by Using Variables


Using Variables as Convenience Constants

The <locale> elements in the weatherlog.xml file, Initial XSLT Example Using Variables, have place attributes whose values are generic for "location1," "location2," and "location3." This enables the application that produces the weatherlog.xml file to be used anywhere.

You can use variables to replace generic names with more meaningful ones. Without variables, you cannot use the following approach to replace the <xsl:value-of select="@place"/> element in the weatherlog.xsl style sheet with an <xsl:choose> block:

<xsl:template match="weather">
   <h1>Weather Readings</h1>
   <xsl:for-each select="day">
      <h2>As of <xsl:value-of select="@date"/></h2>
      <xsl:for-each select="locale">
         <h3>
            <xsl:choose>
                <xsl:when test="@place='locale1'">Midtown</xsl:when>
                <xsl:when test="@place='locale2'">Northeast</xsl:when>
                <xsl:when test="@place='locale3'">Airport</xsl:when>
                <xsl:otherwise>[Unknown Locale]</xsl:otherwise>
            </xsl:choose>
         </h3>
      </xsl:for-each>
   </xsl:for-each>
</xsl:template>

The above solution requires that the <xsl:choose> block be copied everywhere the style sheet needs to be, to make use of the "reader-friendly" place names. The value of the variable named placename can now be used anywhere in this template rule. This makes the value more convenient to use and enhances the style sheet's legibility:

<xsl:template match="weather">
   <h1>Weather Readings</h1>
   <xsl:for-each select="day">
      <h2>As of <xsl:value-of select="@date"/></h2>
      <xsl:for-each select="locale">
         <xsl:variable name="placename">
             <xsl:choose>
                 <xsl:when test="@place='location1'">Midtown</xsl:when>
                 <xsl:when test="@place='location2'">Northeast</xsl:when>
                 <xsl:when test="@place='location3'">Airport</xsl:when>
                 <xsl:otherwise>[Unknown Locale]</xsl:otherwise>
             </xsl:choose>
         </xsl:variable>
         <h3><xsl:value-of select="$placename"/></h3>
      </xsl:for-each>
   </xsl:for-each>
</xsl:template>

Formatted Output

When the above version of the weather template rule is inserted into the weatherlogv1.xsl style sheet, in Initial XSLT Example Using Variables, the result is:

The variable declaration above can be converted to a named template and placed outside the template rule, making its value accessible anywhere in the stylesheet. For more information, see Using Parameters to Store Values that Change.

See Also

Initial XSLT Example Using Variables

Finished XSLT Example Using Variables


Simplifying XPath Expressions by Using Variables

Microsoft XML 4.0 Technology Preview - XSLT Reference

Shortening XPath Expressions by Using Variables

XPath expressions can be long in length, manually typing in the expression can lead to typographical errors. You can shorten complex XPath expressions by using XSLT variables.

You can enhance the weatherlogv1.xsl style sheet to display the average high temperature for each day that is listed in the weatherlog.xml file, in Initial XSLT Example Using Variables. A template rule to display the average high temperature of the day could use the following approach:

<table align="center" width="400">
    <tr>
        <td>Average High Temperature for <xsl:value-of select="@date"/>, All Locales:</td>
        <td>
            <xsl:value-of select="format-number(sum(locale/temp/high) div count(locale), '##0.00')"/>
            &degrees; <xsl:text> </xsl:text><xsl:value-of select="../@temp_scale"/>
        </td>
    </tr>
</table>
Note The above template includes a reference to an entity, &degrees;. This entity is declared in the weatherlog.xsl style sheet as having the value "&#176;", which displays in Microsoft Internet Explorer as the degrees symbol "°".

Instead of specifying the formula and the formatting in the middle of a template, you can define a variable in the template rule to hold the formula's value:

<xsl:variable name="average_temp"
      select="format-number(sum(locale/temp/high) div count(locale), '##0.00')"/>

Short common names that indicate the purpose of the variable, have many advantages. To use the variable in the style sheet, replace the <xsl:value-of> element with the following:

<xsl:value-of select="$average_temp"/>

For more information see, the Finished XSLT Example Using Variables.


Using Parameters to Store Values that Change

XSLT parameters are similar to variables. Each reference to a parameter, consists of a dollar sign followed by the name of the parameter. In addition, each parameter has a value.

The main difference between parameters and variables is that the value of a parameter can change from time to time, during the run of the style sheet, or it can be passed in from an outside environment. The value of a variable, once set, cannot be changed.The following table list two kinds of parameters, you can use in style sheets:

Parameter type | Description | Topic
Local parameters | Used for passing data from one template rule to another. For example, you can pass a parameter to a named template, based on some condition in a given template rule, and thereby control the way that the named template behaves. | Passing Data between Template Rules Using Local Parameters
Global parameters | Used for passing values into a style sheet. This enables the style sheet to perform particular steps depending, on a value supplied by the user. In Internet Explorer, parameters are passed to a style sheet using script. | Passing Values into XSLT Using Global Parameters

See Also

Initial XSLT Example Using Variables

Finished XSLT Example Using Variables


Passing Data between Template Rules Using Local Parameters

To pass a parameter from one template rule to another, use the <xsl:with-param> element as a child of an <xsl:apply-templates> or <xsl:call-template> element. For example:

<xsl:call-template name="some_named_template">
    <xsl:with-param name="param1" select="@some_attrib"/>
</xsl:call-template>

When the XSLT processor encounters the <xsl:call-template> element in a template rule, the template named some_named_template is instantiated. This template then uses the parameter $param1, which in this case contains the value of the context node's some_attrib attribute, to control its processing. (For more information, see Using Variables as Convenience Constants.)

In the previous example the variable's definition had to be placed inside the template rule that used it. Because of limitations in the variable's scope, its value is inaccessible to other template rules, which might make use of it. To resolve this you can use a named template, passing to it the value of the place attribute you are interested in translating.

(For more information, see Considerations when Using Variables and Parameters.)

Compared to the variable-based approach, in Using Variables as Convenience Constants, this approach has the following changes:

  • The <xsl:choose> block is now enclosed in a named template rule, whose name is placename.
  • There is an <xsl:param> element which assigns a string value, "[Unknown Locale]", to the $location parameter as a default, in case a call to this template fails to provide a value.
  • Instead of referencing the @place attribute, you can reference the $location parameter. If the call to the placename template rule supplies a value for the $location parameter, by means of an <xsl:with-param> element, the <xsl:choose> block uses that value.
  • The call to the $placename variable becomes a call to a named template, using the <xsl:with-param> element to pass a parameter.
Note The value of the place attribute is assigned to the $location variable in the <xsl:with-param> element. If that attribute is empty, or has any value other than "location1," "location2," or "location3," the value returned from the named template is "[Unknown Locale]".

Example

This example demonstrates passing data between template rules using local parameters.

XML File (weatherlog.xml)

Use weatherlog.xml, in Initial XSLT Example Using Variables, and make sure the href attribute references the weatherlogv1.xsl style sheet.

XSLT File (weatherlogv1.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/TR/REC-html40">

<xsl:template match="/">
   <html>
      <head>
         <title>Weather Readings</title>
      </head>
      <body>
         <xsl:apply-templates/>
      </body>
   </html>
</xsl:template>

<!-- Override built-in template rule for text nodes -->
<xsl:template match="text()"/>

<xsl:template name="placename">
    <xsl:param name="location" select="'[Unknown Locale]'"/>
    <xsl:choose>
        <xsl:when test="$location='location1'">Midtown</xsl:when>
        <xsl:when test="$location='location2'">Northeast</xsl:when>
        <xsl:when test="$location='location3'">Airport</xsl:when>
        <xsl:otherwise>[Unknown Locale]</xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="weather">
   <h1>Weather Readings</h1>
   <xsl:for-each select="day">
        <xsl:variable name="average_temp"
            select="format-number(sum(locale/temp/high) div count(locale), '##0.00')"/>
      <h2>As of <xsl:value-of select="@date"/></h2>
      <xsl:for-each select="locale">
         <h3>
            <xsl:call-template name="placename">
               <xsl:with-param name="location" select="@place"/>
            </xsl:call-template>
         </h3>
      </xsl:for-each>
   </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Formatted Output

See Also

Initial XSLT Example Using Variables

Finished XSLT Example Using Variables


Passing Values into XSLT Using Global Parameters

Local parameters are called local, because their values are set locally within a template rule and/or named template. Global parameters, have their values set by the environment outside the style sheet. Exactly how the environment establishes those values, and passes them to the style sheet, depends on the XSLT processor. In Microsoft's implementation of the XSLT specification, global parameters are both set and passed using script.

To prepare a style sheet to use global parameters, declare each one with an <xsl:param> element at the top level of the style sheet, that is, as a child of the <xsl:stylesheet> element. The general form is:

<xsl:param name="name" select="default" />

Where name is the parameter's name, as referenced in the style sheet, and "default" is the value that the parameter has, if nothing is supplied, through a controlling script.

Below, you build on the example from Passing Data between Template Rules Using Local Parameters.

In weatherlog.xsl, in Finished XSLT Example Using Variables, you can find the following global parameter declared:

<xsl:param name="place_param" select="'[All]'"/>

The style sheet references the parameter as $place_param. If a script does not supply a value for the parameter, its value by default is the string "[All]". References to the place_param parameter appear three times in the final weatherlog.xsl style sheet, all within the template rule for the <weather> element. The three references are:

  • In the template that instantiates a level-1 heading for the page as a whole:
    <h1>Weather Readings for
    <xsl:choose>
        <xsl:when test="$place_param = '[All]'">
            All Available Locations
        </xsl:when>
        <xsl:otherwise>
            <xsl:call-template name="placename">
                <xsl:with-param name="location" select="$place_param"/>
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</h1>

    The value of place_param is tested to see if it equals "[All]". If it does, the heading reads "Weather Readings for All Available Locations." Otherwise, the heading reads "Weather Readings for Midtown," "...for Northeast," or "...for Airport" according to the value of place_param.

  • An <xsl:choose> block which invokes the template rule for the <locale> element, depending on the value of the parameter. This <xsl:choose> block appears as follows:
    <xsl:choose>
    <xsl:when test="$place_param = '[All]'">
        <xsl:apply-templates select="locale"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:apply-templates select="locale[@place=$place_param]"/>
    </xsl:otherwise>
</xsl:choose>
Note The <locale> element's template rule is invoked in one of two ways.

If the value of the place_param parameter is "[All]" the default, all <locale> elements are selected. This allows the style sheet to be used even if it is not controlled through a script.

  • If the value of place_param is anything else, the <locale> elements are filtered by the XPath expression's predicate [@place=$place_param]That is, the only <locale> elements selected is the one whose place attributes equal the value of the place_param parameter.
  • An <xsl:if> block is used to generate a display of average temperatures across all locales for a given day:
    <xsl:if test="$place_param = '[All]'">
    <div class="locale">
        <table align="center" width="400">
            <tr>
                <td>Average High Temperature for <xsl:value-of select="@date"/>, All Locales:</td>
                <td>
                    <xsl:value-of select="$average_temp"/>
                    &degrees; <xsl:text> </xsl:text><xsl:value-of select="../@temp_scale"/>
                </td>
            </tr>
        </table>
    </div>
</xsl:if>

    If the style sheet is meant to apply to all locations, the average temperature block is displayed; if meant to apply to a specific location, nothing is displayed here.

The script to apply the weatherlog.xsl style sheet to weatherlog.xml (in Initial XSLT Example Using Variables) follows the pattern outlined in the XSLTemplate object topic in the XSLT and DOM section. (For more information, see Increasing Performance by Using the XSLTemplate Object.) In particular, the script includes a line like the following:

objXSLProc.addParameter("place_param", "value_of_place_attrib", "");

Where value_of_place_attrib is "location1," "location2," "location3," or "[All]" depending on whether a particular location, or all locations, are to be displayed. This value could be set in the script in response to user action, such as selecting from among four radio buttons. For example, if the user selected a radio button labeled "Downtown," the script could use the addParameter method to set the value of the place_param parameter to "location1." For more information, see addParameter Method.

See Also

Initial XSLT Example Using Variables

Finished XSLT Example Using Variables


Considerations when Using Variables and Parameters

Variables and parameters can simplify style sheets, make them easier to document and maintain, they do come with some potential problems. There are two problems that you should to be aware of: variable/parameter scope, and result tree fragments.

Variable/Parameter Scope

A variable or parameter is available for use, that is, in scope only, within the body of whatever element is its parent (the <xsl:variable> or <xsl:param> element, respectively). Any descendants of that parent may use the variable; descendants of the parent's sibling elements cannot "see" the variable or parameter at all.

Consider an XSLT style sheet structured according to the following outline:

xsl:stylesheet

xsl:param A (global)

xsl:template 1

xsl:variable B (local)

xsl:template 2

Global parameter $A is defined in an <xsl:param> element which is a child of the root <xsl:stylesheet> element. Since all of the style sheet's content is descended from the <xsl:stylesheet> element, references to $A can occur anywhere in the style sheet.

Local variable $B, on the other hand, is defined in an <xsl:variable> child of <xsl:template> #1. Therefore, references to $B can appear only within the scope of that template rule. Any references to $B in template rule #2, or in any other children of the root <xsl:stylesheet> element, will be invalid. If you try to reference the variable or parameter in such a way, Internet Explorer returns an error message:

A reference to variable or parameter 'var_param_name' cannot be resolved. The variable or parameter may not be defined, or it may not be in scope.

where var_param_name is replaced with the name of the offending variable or parameter.

Result Tree Fragments

When an <xsl:variable> or <xsl:param> element is not empty (that is, when it has no select attribute), its value is a special type defined by the XSLT specification: a result tree fragment. This can introduce special problems if your style sheet then tries to use that variable or parameter's value.

For instance, given weatherlog.xml (in Initial XSLT Example Using Variables), we might construct a variable called weather_data like this:

<xsl:variable name="weather_data">
<xsl:value-of
select="temp|wind_dir|wind_speed|barom|rel_humid|precip"/>
</xsl:variable>

It's natural to think that this variable now consists of a node-set, containing the children of the given <locale> element. But as defined by XSLT, a node-set must have a root element. The "node-set" we've actually established as the value of, say, the location1 <locale> element is:

<temp>
    <low>47</low>
    <high>62</high>
</temp>
<wind_dir>NNE</wind_dir>
<wind_speed units="mph">5</wind_speed>
<barom units="mb">1013.2</barom>
<rel_humid>.74</rel_humid>
<precip units="in">0</precip>

That is, it has no root element and is therefore not a node-set. For this reason, the XSLT specification says that the value of any non-empty <xsl:variable> or <xsl:param> element is always a result tree fragment. And since it's not a node-set, you cannot use a variable or parameter reference in any XSLT or XPath context which expects one. All you can do with a result tree fragment is copy it to the result tree, or perform string operations on it. (In the latter case, the result tree's string value is the concatenated value of all text nodes in the fragment.)

In order to perform node-set operations on a result tree fragment, you must convert the result tree fragment to a node-set using the node-set() extension function.

For more information about this extension function, see Using msxsl:node-set() to Process Result-Tree Fragments.

See Also

Initial XSLT Example Using Variables

Finished XSLT Example Using Variables


Finished XSLT Example Using Variables

The following XSLT file results after you create the template rules described in the topics in this section.

Example

This example demonstrates variables and passing parameters between template rules.

XML File (weatherlog.xml)

Use weatherlog.xml (in Initial XSLT Example Using Variables) and change the href attribute to reference weatherlog.xsl.

XSLT File (weatherlog.xsl)

<?xml version="1.0" ?>
<!-- Declare a character entity for displaying the
    "degrees" symbol to be used in temperature readings -->
<!DOCTYPE xsl:stylesheet [
<!ENTITY degrees "&#176;">
]>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/TR/REC-html40">

<!-- Global parameter for selecting a local -->
<xsl:param name="place_param" select="'[All]'"/>

<!-- Template rule for document root: basic Web page setup -->
<xsl:template match="/">
    <html>
        <head>
            <title>Weather Readings</title>
            <style type="text/css">
                h1 {background-color: gold;
                    font-family: Tahoma,Verdana,Arial,sans-serif;
                    font-size: 24pt}
                h2 {background-color: yellow;
                    font-family: Tahoma,Verdana,Arial,sans-serif;
                    font-size: 18pt}
                h3 {background-color: teal;
                    font-family: Tahoma,Verdana,Arial,sans-serif;
                    font-size: 14pt;
                    font-weight: bold;
                    text-align: center}
                th {background-color: silver;
                    font-family: Tahoma,Verdana,Arial,sans-serif}
                td {background-color: white;
                    font-family: Tahoma,Verdana,Arial,sans-serif}
                .locale {width: 500;
                    border: 1px;
                    border-style: solid;
                    margin: 10px}
            </style>
        </head>
        <body>
            <xsl:apply-templates/>
        </body>
    </html>
</xsl:template>

<!-- Override built-in template rule for text nodes
    (suppress any text unless explicitly requested) -->
<xsl:template match="text()"/>

<!-- Named template rule "placename" returns user-friendly name of
    a locale, given known generic values of "location1," and so on -->
<xsl:template name="placename">
    <xsl:param name="location" select="'[Unknown Locale]'"/>
    <xsl:choose>
        <xsl:when test="$location='location1'">Midtown</xsl:when>
        <xsl:when test="$location='location2'">Northeast</xsl:when>
        <xsl:when test="$location='location3'">Airport</xsl:when>
        <xsl:otherwise>[Unknown Locale]</xsl:otherwise>
    </xsl:choose>
</xsl:template>

<!-- Template rule for root <weather> element -->
<xsl:template match="weather">
    <!-- Set up major page heading depending on value of global
        parameter "place_param" -->
    <h1>Weather Readings for
        <xsl:choose>
            <xsl:when test="$place_param = '[All]'">
                All Available Locations
            </xsl:when>
            <xsl:otherwise>
                <xsl:call-template name="placename">
                    <xsl:with-param name="location" select="$place_param"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </h1>
    <!-- Process <day> children of <weather> element -->
    <xsl:for-each select="day">
        <!-- Variable "average_temp" holds formatted version of average
            high temperature, across all locales for a given day -->
        <xsl:variable name="average_temp"
            select="format-number(sum(locale/temp/high) div count(locale), '##0.00')"/>
        <h2>As of <xsl:value-of select="@date"/></h2>
        <xsl:choose>
            <!-- If global parameter "place_param" is the default "[All]",
                process all <locale> children of the <day> element... -->
            <xsl:when test="$place_param = '[All]'">
                <xsl:apply-templates select="locale"/>
            </xsl:when>
            <!-- ...otherwise, filter the <locale> children of the <day>
                element, selecting only those matching the requested locale. -->
            <xsl:otherwise>
                <xsl:apply-templates select="locale[@place=$place_param]"/>
            </xsl:otherwise>
        </xsl:choose>
        <!-- If processing all locales (per "place_param" global parameter),
            add a block displaying the average high temperature across all
            locales. -->
        <xsl:if test="$place_param = '[All]'">
            <div class="locale">
                <table align="center" width="400">
                    <tr>
                        <td>Average High Temperature for <xsl:value-of select="@date"/>, All Locales:</td>
                        <td>
                            <xsl:value-of select="$average_temp"/>
                            &degrees; <xsl:text> </xsl:text><xsl:value-of select="../@temp_scale"/>
                        </td>
                    </tr>
                </table>
            </div>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

<!-- Template rule for <locale> elements: set up a label for the
    locale (using "user-friendly" form of location name returned
    by the "placename" named template, followed by a table of
    this locale's weather readings -->
<xsl:template match="locale">
    <div class="locale">
        <h3>
            <xsl:call-template name="placename">
                <xsl:with-param name="location" select="@place"/>
            </xsl:call-template>
        </h3>
        <table align="center">
            <tr>
                <th>Temp Range</th>
                <th>Wind</th>
                <th>Barometer</th>
                <th>Humidity</th>
                <th>Precipitation</th>
            </tr>
            <tr>
                <td align="center">
                    <xsl:value-of select="concat(temp/low, '-', temp/high)"/>
                    &degrees; <xsl:text> </xsl:text><xsl:value-of select="/weather/@temp_scale"/>
                </td>
                <td align="center">
                    <xsl:value-of select="concat(wind_speed, ' ', wind_speed/@units)"/>
                    <xsl:value-of select="concat(' from ', wind_dir)"/>
                </td>
                <td align="center">
                    <xsl:value-of select="concat(barom, barom/@units)"/>
                </td>
                <td align="right">
                    <xsl:value-of select="concat(string(rel_humid * 100), '%')"/>
                </td>
                <td align="right">
                    <xsl:value-of select="concat(precip, ' ', precip/@units)"/>
                </td>
            </tr>
        </table>
    </div>
</xsl:template>

</xsl:stylesheet>

Formatted Output

See Also

Initial XSLT Example Using Variables


Sorting with XSLT

Using XSLT to sort data in an XML document is mostly straightforward. For each "sort key" you want to use for a given element, place an <xml:sort> element as a child of either the <xsl:for-each> or the <xsl:apply-templates> element which controls processing of a group of the element type to be sorted.

This section covers the following:

  • Basic Sorting in XSLT
  • Sorting on Calculated Variables

Topics in this section use the Sample XML Data File for XSLT Sorting.

See Also

xsl:sort Element


Basic Sorting in XSLT

XSLT supports sorting, such as sorting rows in a table.

This section covers the following:

  • Sorting in Document Order by Default
  • Sorting by a Single Column
  • Sorting by Two Columns
  • Sorting Data by Numeric Value


Sorting in Document Order by Default

To introduce basic sorting, first we start with a complete example that does not sort the rows.

In Internet Explorer, the default display a straightforward table is to display the document's content in the order it appeared in the document.. This default sort order is the document order.

It's not that hard to locate a product of a particular name, category, or other characteristic in such a short display. But as the number of products grew, we'd probably want to have our output in some kind of sequence for easy reference.

Example

This XSLT style sheet processes the prod_sort.xml file (shown in Sample XML Data File for XSLT Sorting) to produce a simple table with rows for each product and columns for data such as the product category and product number.

XML File (prod_sort.xml)

Use prod_sort.xml (shown in Sample XML Data File for XSLT Sorting) and change the href attribute to reference prodsort0.xsl.

XSLT File (prodsort0.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <html>
      <head>
         <title>Wooden Rings and More!</title>
         <style type="text/css">
            th {background-color: silver;
               font-family: Tahoma,Verdana,Arial,sans-serif}
            td {background-color: white;
               font-family: Tahoma,Verdana,Arial,sans-serif}
         </style>
      </head>
      <body>
         <xsl:apply-templates/>
      </body>
   </html>
</xsl:template>

<xsl:template match="products">
   <table width="75%">
      <tr>
         <th>Category</th>
         <th>Prod ID</th>
         <th>Name/Version</th>
         <th>Description</th>
         <th>Price/Units</th>
      </tr>
      <xsl:apply-templates/>
   </table>
</xsl:template>

<xsl:template match="product">
   <tr>
      <td valign="top"><xsl:value-of select="categ"/></td>
      <td valign="top"><xsl:value-of select="@prodID"/></td>
      <td valign="top"><xsl:value-of select="concat(name, '/', version)"/></td>
      <td valign="top"><xsl:value-of select="descr"/></td>
      <td valign="top" align="center"><xsl:value-of select="concat(price, ' (', price/@curr, ')')"/></td>
      <td valign="top" align="right"><xsl:value-of select="usd_equiv"/></td>
   </tr>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

A portion of the output is shown here.

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-16">
<title>Wooden Rings and More!</title>
<style type="text/css">
            th {background-color: silver;
               font-family: Tahoma,Verdana,Arial,sans-serif}
            td {background-color: white;
               font-family: Tahoma,Verdana,Arial,sans-serif}
         </style>
</head>
<body>
<table width="75%">
<tr>
<th>Category</th>
<th>Prod ID</th>
<th>Name/Version</th>
<th>Description</th>
<th>Price/Units</th>
</tr>
<tr>
<td valign="top">Software</td>
<td valign="top">AX5608</td>
<td valign="top">FooBar/1.5</td>
<td valign="top">Processes foo objects using standard FB API</td>
<td valign="top" align="center">149.99 (USD)</td>
<td valign="top" align="right"></td>
</tr>
...
</table>
</body>
</html>


Sorting by a Single Column

In this topic, we add a single <xsl:sort> element to the above unsorted example.

Example

Processing of individual <product> elements is performed by a separate product template rule, invoked as a result of the <xsl:apply-templates> element in the products template rule. We want to sort our products by category. To do so, add an <xsl:sort> element as a child of the <xsl:apply-templates> element in the products template rule.

Note The <xsl:apply-templates> element, typically empty, must be changed to a non-empty start tag/end tag pair. Also note that the value of the <xsl:sort> element's select attribute is relative to the context node established by the <xsl:apply-templates> element, not to the one established by the <xsl:template> element's match attribute. That is, the following:
<xsl:sort select="product/categ"/>

will not work correctly.

XML File (prod_sort.xml)

Use prod_sort.xml (shown in Sample XML Data File for XSLT Sorting) and change the href attribute to reference prodsort1.xsl.

XSLT File (prodsort1.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <html>
      <head>
         <title>Wooden Rings and More!</title>
         <style type="text/css">
            th {background-color: silver;
               font-family: Tahoma,Verdana,Arial,sans-serif}
            td {background-color: white;
               font-family: Tahoma,Verdana,Arial,sans-serif}
         </style>
      </head>
      <body>
         <xsl:apply-templates/>
      </body>
   </html>
</xsl:template>

<xsl:template match="products">
    <table width="75%">
        <tr>
            <th>Category</th>
            <th>Prod ID</th>
            <th>Name/Version</th>
            <th>Description</th>
            <th>Price/Units</th>
        </tr>
        <xsl:apply-templates>
            <xsl:sort select="categ"/>
        </xsl:apply-templates>
    </table>
</xsl:template>

<xsl:template match="product">
   <tr>
      <td valign="top"><xsl:value-of select="categ"/></td>
      <td valign="top"><xsl:value-of select="@prodID"/></td>
      <td valign="top"><xsl:value-of select="concat(name, '/', version)"/></td>
      <td valign="top"><xsl:value-of select="descr"/></td>
      <td valign="top" align="center"><xsl:value-of select="concat(price, ' (', price/@curr, ')')"/></td>
      <td valign="top" align="right"><xsl:value-of select="usd_equiv"/></td>
   </tr>
</xsl:template>

</xsl:stylesheet>

Formatted Ouput


Sorting by Two Columns

The above example makes it much easier to locate products of a particular category. However, within each category, products are still listed in the order in which they appear in the original document. So we'd probably want to make finding products even simpler, perhaps by sorting on product name within each category. We can add a second such sort level to the first using a second <xsl:sort> element.

Example

In the results, note that within the Craftware category, the products are now listed by alphabetical order.

XML File (prod_sort.xml)

Use prod_sort.xml (shown in Sample XML Data File for XSLT Sorting) and change the href attribute to reference prodsort2.xsl.

XSLT File (prodsort2.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <html>
      <head>
         <title>Wooden Rings and More!</title>
         <style type="text/css">
            th {background-color: silver;
               font-family: Tahoma,Verdana,Arial,sans-serif}
            td {background-color: white;
               font-family: Tahoma,Verdana,Arial,sans-serif}
         </style>
      </head>
      <body>
         <xsl:apply-templates/>
      </body>
   </html>
</xsl:template>

<xsl:template match="products">
    <table width="75%">
        <tr>
            <th>Category</th>
            <th>Prod ID</th>
            <th>Name/Version</th>
            <th>Description</th>
            <th>Price/Units</th>
        </tr>
        <xsl:apply-templates>
            <xsl:sort select="categ"/>
            <xsl:sort select="name"/>
        </xsl:apply-templates>
    </table>
</xsl:template>

<xsl:template match="product">
   <tr>
      <td valign="top"><xsl:value-of select="categ"/></td>
      <td valign="top"><xsl:value-of select="@prodID"/></td>
      <td valign="top"><xsl:value-of select="concat(name, '/', version)"/></td>
      <td valign="top"><xsl:value-of select="descr"/></td>
      <td valign="top" align="center"><xsl:value-of select="concat(price, ' (', price/@curr, ')')"/></td>
      <td valign="top" align="right"><xsl:value-of select="usd_equiv"/></td>
   </tr>
</xsl:template>

</xsl:stylesheet>

Formatted Ouput


Sorting Data by Numeric Value

When you want to sort on a value of some data type other than string, use the data-type attribute of the <xsl:sort> element. This attribute can take three possible values: "text," "number," or a qualified name.

Note A qualified name (often called a "Qname") includes an optional namespace prefix and a local-name part, for example ms:date. The XSLT specification does not indicate how a Qname is to be used, but it is expected that vendors may supply their own data types, such as date, binary, and so on. This version of the MSXML XSLT processor does not support Qnames used as the value of the <xsl:sort> element's data-type attribute.

The reason for specifying a data type other than the default "text" is that non-text values may sort improperly if treated as text. For example, the following are sorted correctly as text, but incorrectly as numbers:

1004
109
12

The default text sort order compares the values by looking at each character in each value from left to right: "100" is less than "109," so a string beginning with "100" sorts ahead of one beginning with "109." And the leading "10" in both "1004" and "109" sorts ahead of the "12." We almost certainly want these values to be treated as numbers, and sort them as:

12
109
1004

That is, the number 12 is less than the number 109, which in turn is less than the number 1004.

To this point, our sorted table based on prod_sort.xml displays products sorted first by categories and then, within each category, by product name. Notice, though, that there are two version of the Wooden Rings Workbench product, and that the corresponding two rows of the table are still in document order. Let's add a third sort level to the existing two:

Example

Comparing this example's result to the previous version of the table, note that Wooden Rings Workbench versions 4.0 and 4.5 have switched places.

Even though the version number doesn't display as a separate column, it (or any other document content, even that which is not displayed at all) can still be used as a sort key.

XML File (prod_sort.xml)

Use prod_sort.xml (shown in Sample XML Data File for XSLT Sorting) and change the href attribute to reference prodsort3.xsl.

XSLT File (prodsort3.xsl)

This is the final version of this series of XSLT files.

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <html>
      <head>
         <title>Wooden Rings and More!</title>
         <style type="text/css">
            th {background-color: silver;
               font-family: Tahoma,Verdana,Arial,sans-serif}
            td {background-color: white;
               font-family: Tahoma,Verdana,Arial,sans-serif}
         </style>
      </head>
      <body>
         <xsl:apply-templates/>
      </body>
   </html>
</xsl:template>

<xsl:template match="products">
    <table width="75%">
        <tr>
            <th>Category</th>
            <th>Prod ID</th>
            <th>Name/Version</th>
            <th>Description</th>
            <th>Price/Units</th>
        </tr>
        <xsl:apply-templates>
            <xsl:sort select="categ"/>
            <xsl:sort select="name"/>
            <xsl:sort select="version" data-type="number"/>
        </xsl:apply-templates>
    </table>
</xsl:template>

<xsl:template match="product">
   <tr>
      <td valign="top"><xsl:value-of select="categ"/></td>
      <td valign="top"><xsl:value-of select="@prodID"/></td>
      <td valign="top"><xsl:value-of select="concat(name, '/', version)"/></td>
      <td valign="top"><xsl:value-of select="descr"/></td>
      <td valign="top" align="center"><xsl:value-of select="concat(price, ' (', price/@curr, ')')"/></td>
      <td valign="top" align="right"><xsl:value-of select="usd_equiv"/></td>
   </tr>
</xsl:template>

</xsl:stylesheet>

Formatted Ouput


Sorting on Calculated Variables

The sorting performed by the <xsl:sort> elements above, in prod_sort.xsl, would be suitable for an application like a catalog, in which a given product needs to be located easily.

Suppose, though, that the corporation's chief financial officer asks to see a list of all products arranged in order by retail price. The first problem this presents is that our data contains a mixture prices in various currency denominations: US dollars (curr="USD"), Euros (curr="EU"), and British pounds Stirling (curr="GBP"). But getting over that hurdle seems easy enough, right? You could just define a variable, say usd_equiv, which will hold the product's retail price converted to its US dollar equivalent, and sort on that rather than the raw <price> element's value.

The problem is that you can't sort directly on a variable. The sort key used as the value of the <xsl:sort> element's select attribute has to be an XPath expression of some kind.

However, you can sort on a calculated value using the following general set of steps:

  1. Clone the source tree into a variable, which will then hold a result tree fragment. For more information, see Considerations when Using Variables and Parameters and Introduction to Result Tree Fragments.
  2. Create a new element to hold the calculated result, and append this new element to the cloned source tree created in step 1.
  3. Select and sort not the original source tree, but the result tree fragment created by steps 1 and 2. Note that this will require the result tree fragment to be converted to a node-set, using the msxsl:node-set() function. For more information, see Using msxsl:node-set() to Process Result-Tree Fragments.

We'll work through each of these steps for our sample data in the remainder of this topic. You can see the complete prod_sort_curr.xsl style sheet which solves this puzzle, in Sample XSLT File for Sorting.

  • Step 1: Cloning the Source Tree
  • Step 2: Creating the New Element
  • Step 3: Sorting the Source Tree Clone


Step 1: Cloning the Source Tree

We're going to do most of the processing in our style sheet using the template rules shown in the following XSLT file. The first template rule handles the root <products> element. The first step in that template rule creates a variable, prods_with_usd. The contents of that variable consist of a result tree fragment, generated by the second template rule, which contains a copy of each <product> element, its attributes, and its children. (Note the use of the mode attribute, which causes this second template rule to be fired only when the <apply-templates> element has a matching mode.)

After making the changes shown below, the prods_with_usd variable (a result tree fragment) simply contains a root node, the seven <product> elements, and their children. If we stopped here, there'd be no difference in the data available to be sorted.

XML File (prod_sort.xml)

Use prod_sort.xml (shown in Sample XML Data File for XSLT Sorting) and change the href attribute to reference prodsortcvar1.xsl.

XSLT File (prodsortcvar1.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <html>
      <head>
         <title>Wooden Rings and More!</title>
         <style type="text/css">
            th {background-color: silver;
               font-family: Tahoma,Verdana,Arial,sans-serif}
            td {background-color: white;
               font-family: Tahoma,Verdana,Arial,sans-serif}
         </style>
      </head>
      <body>
         <xsl:apply-templates/>
      </body>
   </html>
</xsl:template>

<xsl:template match="products">
    <!-- Create a variable to hold the generated result tree fragment -->
    <xsl:variable name="prods_with_usd">
        <xsl:apply-templates select="product" mode="calc_usd" />
    </xsl:variable>
    <table width="75%">
        <tr>
            <th>Category</th>
            <th>Prod ID</th>
            <th>Name/Version</th>
            <th>Description</th>
            <th>Price (Currency)</th>
            <th>Price (USD)</th>
        </tr>
    </table>
</xsl:template>

<xsl:template match="product" mode="calc_usd">
    <xsl:copy>
        <xsl:copy-of select="@*" />
        <xsl:copy-of select="*" />
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>


Step 2: Creating the New Element

Now we're going to add code to the second template rule above — the one fired as a result of the mode="calc_used" attribute — to create for each <product> element a new child, called <usd_equiv>, which contains the equivalent, in US dollars, of whatever that product's price is in local currency. This template rule, with changes highlighted, will now look like the listing below.

Note The element created by the <xsl:element> here could also have been created as a simple literal result element. That is, the <xsl:element name="usd_equiv"> start tag could be replaced with <usd_equiv>, and the </xsl:element> end tag with </usd_equiv>.

As a result of the changes below, we have a variable, prods_with_usd, which contains a result tree fragment consisting of each product's data copied from the source tree — plus (for each product) the all-important new element, <usd_equiv>. All that's left is to apply the sort to this slightly altered source tree clone, and place its results in table rows (one per product).

XML File (prod_sort.xml)

Use prod_sort.xml (shown in Sample XML Data File for XSLT Sorting) and change the href attribute to reference prodsortcvar2.xsl.

XSLT File (prodsortcvar2.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <html>
      <head>
         <title>Wooden Rings and More!</title>
         <style type="text/css">
            th {background-color: silver;
               font-family: Tahoma,Verdana,Arial,sans-serif}
            td {background-color: white;
               font-family: Tahoma,Verdana,Arial,sans-serif}
         </style>
      </head>
      <body>
         <xsl:apply-templates/>
      </body>
   </html>
</xsl:template>

<xsl:template match="products">
    <!-- Create a variable to hold the generated result tree fragment -->
    <xsl:variable name="prods_with_usd">
        <xsl:apply-templates select="product" mode="calc_usd" />
    </xsl:variable>
    <table width="75%">
        <tr>
            <th>Category</th>
            <th>Prod ID</th>
            <th>Name/Version</th>
            <th>Description</th>
            <th>Price (Currency)</th>
            <th>Price (USD)</th>
        </tr>
    </table>
</xsl:template>

<xsl:template match="product" mode="calc_usd">
    <xsl:copy>
        <xsl:copy-of select="@*" />
        <xsl:copy-of select="*" />
        <!-- Add a calculated <usd_equiv> child to each <product> -->
        <xsl:element name="usd_equiv">
            <xsl:choose>
                <!-- Note: Exchange rates current as of Oct. 2000 -->
                <xsl:when test="price/@curr='USD'">
                    <xsl:value-of select="format-number(price, '#,##0.00')"/>
                </xsl:when>
                <xsl:when test="price/@curr='GBP'">
                    <xsl:value-of select="format-number(price * 1.47275, '#,##0.00')"/>
                </xsl:when>
                <xsl:when test="price/@curr='EU'">
                    <xsl:value-of select="format-number(price * 0.864379, '#,##0.00')"/>
                </xsl:when>
                <xsl:otherwise>Unknown Currency</xsl:otherwise>
            </xsl:choose>
        </xsl:element>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>


Step 3: Sorting the Source Tree Clone

To sort the modified clone of the source tree, we need to convert it to a node-set using the msxsl:node-set() function and then pass it, in its sorted form, to a plain-vanilla template rule that handles it more or less exactly as the original source tree itself would be handled.

The sort is effected by adding some new lines to the template rule for the root <products> element, as featured below:

To use the msxsl:node-set() function, the style sheet's <xml:stylesheet> element must include the following namespace declaration:

xmlns:msxsl="urn:schemas-microsoft-com:xslt"

Example

In the results, the Virtual Widgets product has changed position significantly, relative to the order it would have been in had we simply sorted on the <price> element alone.

Also note the use of the new <usd_equiv> element's value in the last column of the table.

For this technique to work, the style sheet must not include a namespace declaration for the HTML 4.0 namespace, which you will typically include when transforming XML to HTML compatible with Internet Explorer. The reason is that the generated <usd_equiv> element, which includes no namespace prefix, is in the default namespace — and since <usd_equiv> is not an HTML element, it will "disappear" from the result tree.

XML File (prod_sort.xml)

Use prod_sort.xml (shown in Sample XML Data File for XSLT Sorting) and change the href attribute to reference prodsortcvar.xsl.

XSLT File (prodsortcvar.xsl)

The product template rule with a mode and a new <xsl:apply-templates> element invokes a template rule used for <product> elements with no mode attribute. These two template rules are shown below, and prodsortcvar.xsl file is now complete. The complete prodsortcvar.xsl file is shown in Sample XSLT File for Sorting.

<xsl:template match="products">
    <!-- Create a variable to hold the generated result tree fragment -->
    <xsl:variable name="prods_with_usd">
        <xsl:apply-templates select="product" mode="calc_usd" />
    </xsl:variable>
    <table width="75%">
        <tr>
            <th>Category</th>
            <th>Prod ID</th>
            <th>Name/Version</th>
            <th>Description</th>
            <th>Price (Currency)</th>
            <th>Price (USD)</th>
        </tr>
        <!-- Fill remainder of table with source tree "clone" -->
        <xsl:apply-templates select="msxsl:node-set($prods_with_usd)/product">
            <xsl:sort select="usd_equiv" data-type="number" />
        </xsl:apply-templates>
    </table>
</xsl:template>

<xsl:template match="product">
    <tr>
        <td valign="top"><xsl:value-of select="categ"/></td>
        <td valign="top"><xsl:value-of select="@prodID"/></td>
        <td valign="top"><xsl:value-of select="concat(name, '/', version)"/></td>
        <td valign="top"><xsl:value-of select="descr"/></td>
        <td valign="top" align="center"><xsl:value-of select="concat(price, ' (', price/@curr, ')')"/></td>
        <td valign="top" align="right"><xsl:value-of select="usd_equiv"/></td>
    </tr>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

A portion of the output is shown here.

<html xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-16">
<title>Wooden Rings and More!</title>
<style type="text/css">
            th {background-color: silver;
               font-family: Tahoma,Verdana,Arial,sans-serif}
            td {background-color: white;
               font-family: Tahoma,Verdana,Arial,sans-serif}
         </style>
</head>
<body>
<table width="75%">
<tr>
<th>Category</th>
<th>Prod ID</th>
<th>Name/Version</th>
<th>Description</th>
<th>Price (Currency)</th>
<th>Price (USD)</th>
</tr>
<tr>
<td valign="top">Craftware</td>
<td valign="top">WR1016</td>
<td valign="top">Wooden Rings/1.6</td>
<td valign="top">Our best-selling oaken toroids</td>
<td valign="top" align="center">27.99 (USD)</td>
<td valign="top" align="right">27.99</td>
</tr>
<tr>
<td valign="top">Software</td>
...
</table>
</body>
</html>


Sample XSLT File for Sorting

This is the complete final file for the topics in the Sorting on Calculated Variables section.

XSLT File (prodsortcvar.xsl)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:msxsl="urn:schemas-microsoft-com:xslt">

<xsl:template match="/">
   <html>
      <head>
         <title>Wooden Rings and More!</title>
         <style type="text/css">
            th {background-color: silver;
               font-family: Tahoma,Verdana,Arial,sans-serif}
            td {background-color: white;
               font-family: Tahoma,Verdana,Arial,sans-serif}
         </style>
      </head>
      <body>
         <xsl:apply-templates/>
      </body>
   </html>
</xsl:template>

<xsl:template match="products">
   <!-- Create a variable to hold the generated result tree fragment -->
   <xsl:variable name="prods_with_usd">
      <xsl:apply-templates select="product" mode="calc_usd" />
   </xsl:variable>
   <table width="75%">
      <tr>
         <th>Category</th>
         <th>Prod ID</th>
         <th>Name/Version</th>
         <th>Description</th>
         <th>Price (Currency)</th>
         <th>Price (USD)</th>
      </tr>
      <!-- Fill remainder of table with source tree "clone" -->
      <xsl:apply-templates select="msxsl:node-set($prods_with_usd)/product">
         <xsl:sort select="usd_equiv" data-type="number" />
      </xsl:apply-templates>
   </table>
</xsl:template>

<xsl:template match="product" mode="calc_usd">
   <xsl:copy>
      <xsl:copy-of select="@*" />
      <xsl:copy-of select="*" />
      <!-- Add a calculated <usd_equiv> child to each <product> -->
      <xsl:element name="usd_equiv">
         <xsl:choose>
            <!-- Note: Exchange rates current as of Oct. 2000 -->
            <xsl:when test="price/@curr='USD'">
               <xsl:value-of select="format-number(price, '#,##0.00')"/>
            </xsl:when>
            <xsl:when test="price/@curr='GBP'">
               <xsl:value-of select="format-number(price * 1.47275, '#,##0.00')"/>
            </xsl:when>
            <xsl:when test="price/@curr='EU'">
               <xsl:value-of select="format-number(price * 0.864379, '#,##0.00')"/>
            </xsl:when>
            <xsl:otherwise>Unknown Currency</xsl:otherwise>
         </xsl:choose>
      </xsl:element>
   </xsl:copy>
</xsl:template>

<xsl:template match="product">
   <tr>
      <td valign="top">
         <xsl:value-of select="categ"/>
      </td>
      <td valign="top">
         <xsl:value-of select="@prodID"/>
      </td>
      <td valign="top">
         <xsl:value-of select="concat(name, '/', version)"/>
      </td>
      <td valign="top">
         <xsl:value-of select="descr"/>
      </td>
      <td valign="top" align="center">
         <xsl:value-of select="concat(price, ' (', price/@curr, ')')"/>
      </td>
      <td valign="top" align="right">
         <xsl:value-of select="usd_equiv"/>
      </td>
   </tr>
</xsl:template>

</xsl:stylesheet>


Sample XML Data File for XSLT Sorting

The following XML file contains data about a vendor's products. It is used by XSLT files presented in the Sorting section.

XML File (prod_sort.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="prodsort.xsl" ?>
<products>
    <product prodID="AX5608">
        <name>FooBar</name>
        <version>1.5</version>
        <descr>Processes foo objects using standard FB API</descr>
        <categ>Software</categ>
        <price curr="USD">149.99</price>
        <units>each</units>
    </product>
    <product prodID="CB3241">
        <name>TrixelMaker</name>
        <version>3.0</version>
        <descr>Burns multiple trixels from single master (requires Wooden Rings 1.6 or greater)</descr>
        <categ>Hardware</categ>
        <price curr="EU">178.49</price>
        <units>each</units>
    </product>
    <product prodID="WD3241">
        <name>Widgetry Magick</name>
        <version>1.0</version>
        <descr>Time-stamps Virtual Widgets</descr>
        <categ>Software</categ>
        <price curr="GBP">46.80</price>
        <units>each</units>
    </product>
    <product prodID="WR9843">
        <name>Wooden Rings Workbench</name>
        <version>4.5</version>
        <descr>Enhances WRWB 4.0 with "peel'n'play" capability</descr>
        <categ>Craftware</categ>
        <price curr="USD">129.95</price>
        <units>each</units>
    </product>
    <product prodID="WR9840">
        <name>Wooden Rings Workbench</name>
        <version>4.0</version>
        <descr>Applies Widgetry Magick timestamps to Wooden Rings 1.6 or greater</descr>
        <categ>Craftware</categ>
        <price curr="USD">109.95</price>
        <units>each</units>
    </product>
    <product prodID="WR1016">
        <name>Wooden Rings</name>
        <version>1.6</version>
        <descr>Our best-selling oaken toroids</descr>
        <categ>Craftware</categ>
        <price curr="USD">27.99</price>
        <units>dozen</units>
    </product>
    <product prodID="WD">
        <name>Virtual Widgets</name>
        <version>3.5</version>
        <descr>Logs critical events and properties over any object's lifetime</descr>
        <categ>Middleware</categ>
        <price curr="GBP">109.99</price>
        <units>each</units>
    </product>
</products>


Working with Namespaces and Prefix Aliases

Understanding the importance and use of namespaces is critical to successfully understanding and using XSLT itself. This topic covers the basic reasons why namespaces are important and some of the nuances of namespaces, which you may encounter in your own XSLT work. This section also examines certain advanced features of namespaces that you will likely not need to use for any of your style sheets.

  • Introduction to Namespaces in XSLT
  • Declaring Namespaces for XSLT
  • Changing Namespace Aliases Programmatically

See Also

xsl:namespace-alias Element


Introduction to Namespaces in XSLT

A namespace is a "universe of names" — in effect, an XML vocabulary. All elements and attributes present in a particular XML vocabulary occupy the same namespace. For instance, strictly speaking, XHTML (the XML-based form of the familiar HTML used to build Web pages) contains such elements as <html>, <body>, <img>, and <a>, most of which have their own attributes like src, href, and the like. All of these element and attribute names share the XHTML namespace. Within a typical XML document, all elements and attributes will be from the same namespace.

A special problem arises in applications like XSLT, which must in a given document include elements and attributes from more than one namespace. For instance, the following XSLT fragment — which does not use any namespaces — would be confusing not only for human readers but also for an XSLT processor:

<element name="chemical">
    <element name="Au">gold</element>
</element>

We might guess that the purpose of this fragment is to create an element (that is, an element in the markup sense) named "chemical" in the result tree, and within that <chemical> element create a child element named "element" (that is, an element in the chemical sense). But there's nothing inherent in the markup of this fragment which would lead us to this conclusion; it might simply be literal markup, whose corresponding nodes are to be placed in their entirety into the result tree. In short, there is nothing to distinguish the namespaces from which the two references to an <element> come.

The World Wide Web Consortium (W3C) developed a special standard, Namespaces in XML, to help circumvent the problem of clashing or potentially clashing namespaces. The general solution is to associate a namespace prefix with a given namespace; elements whose names are associated with that prefix appear in the document in the form:

prefix:name

rather than just as their names alone. In XSLT style sheets, the namespace prefix most commonly used is xsl:, and so the ambiguity of the above fragment could be eliminated as follows:

<xsl:element name="chemical">
    <element name="Au">gold</element>
</xsl:element>

Now the intent is clear, since in lexical terms the name "xsl:element" is not the same as "element".

Note Technically, attribute names without a prefix are assumed to be in no namespace in particular. It may be convenient or more easily understandable if, in the above example, you imagine the name attribute whose value is "chemical" to be in the XSLT namespace; just be aware that this is not strictly speaking the case. The only attributes specifically in some namespace are those whose names carry a namespace prefix.

For more information on how to associate a particular prefix with a particular namespace, see the next section, Declaring Namespaces for XSLT.


Declaring Namespaces for XSLT

To declare a namespace, use a special attribute xmlns (followed, if needed, by a colon and the prefix associated with elements and attributes in that namespace) whose value is a Uniform Resource Identifier (URI) unique to that namespace. This namespace declaration will be in scope for all elements contained by the element in which you place the declaration (unless overridden by some other namespace declaration for the same prefix).

For example, a typical XSLT stylesheet whose purpose is to transform the source tree to HTML begins with an <xsl:stylesheet> start tag which looks like this:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/TR/REC-html40" >

The xmlns:xsl attribute says that the prefix xsl: on an element or attribute name means that any such element or attribute is from the namespace associated with the URI "http://www.w3.org/1999/XSL/Transform" — that is, the XSLT namespace. Therefore, any elements and attribute names so prefixed will be assumed to be an instruction to an XSLT processor, such as the one built into Microsoft Internet Explorer.

The xmlns attribute, on the other hand, says that element names with no prefix will be from the namespace associated with the URI "http://www.w3.org/TR/REC-html40" — that is, the HTML namespace.

There are two considerations in declaring a namespace: what prefix to use, and what URI to associate with that prefix.

  • The choice of a namespace prefix is unimportant to the XSLT processor (although it should be meaningful for human readers, of course, for self-documenting purposes). The main constraint is that it must be a valid XML name (start with a letter or underscore, and have no embedded spaces). Thus, an XSLT style sheet might just as well use the prefixes xslt:, transform:, XSLT_Stylesheet_Prefix:, and so on, rather than the conventional xsl:.
  • Which URI to use, though, is critically important. In the case of XSLT style sheets, an XSLT processor will regard as an instruction any element or attribute whose name begins with the prefix associated with the XSLT namespace URI, http://www.w3.org/1999/XSL/Transform. If you change even a single character of this namespace URI, the XSLT processor will assume that an element or attribute whose name starts with the given prefix is something other than an XSLT instruction.
    Note Not all URIs take the form of a traditional Uniform Resource Locator (URL), such as http://www.mycompany.com. In the case of the MSXML processor, in particular, Microsoft extensions to the XSLT standard (such as the msxsl:node-set() function) are identified by a prefix associated with the URI "urn:schemas-microsoft-com:xslt", as in the following namespace declaration:
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"

    This URI form is called a Uniform Resource Name (URN). Again, whether the URI takes the form of a locator or a name, the specific URI cannot be changed if you want to take advantage of a feature supported by a particular processor.

See Also

Declaring Namespaces


Example of Declaring Namespaces in XSLT

Example

This example produces a table that lists each element in the style sheet, in document order, and some information about its parent to help orient you to which instance of that element a given row in the table refers to. The table shows the namespaces in effect for that element: which namespace the element itself is in, and all of the namespaces currently in scope at that point.

To view this example, view the XSLT file in Internet Explorer.

XML File

No XML file is required, because the XSLT file calls itself.

You could use the Sample XML File (books.xml). Below the line <?xml version='1.0'?>, add the following line:

<?xml-stylesheet type="text/xsl" href="ns_decl.xsl"?>

XSLT File (ns_decl.xsl)

This file invokes itself, so you can view it directly in Internet Explorer. You could also use this style sheet with any XML document. Code related to namespaces is highlighted.

<?xml-stylesheet type="text/xsl" href="ns_decl.xsl"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/TR/REC-html40" >

<xsl:template match="text()"/>

<xsl:template match="/">
    <html>
    <body><table border="1">
        <tr style="background-color: silver">
            <th>Child Name</th>
            <th>Parent</th>
            <th>Child #</th>
            <th>Namespace URI</th>
            <th>Namespace(s) in Scope</th>
        </tr>
        <xsl:apply-templates/>
    </table></body>
    </html>
</xsl:template>

<xsl:template match="*">
    <tr>
        <td valign="top"><xsl:value-of select="name()"/></td>
        <transform:variable name="root_or_name"
            xmlns:transform="http://www.w3.org/1999/XSL/Transform">
            <transform:choose>
                <xsl:when test="name(..)=''">--ROOT--</xsl:when>
                <transform:otherwise>
                    <transform:value-of select="name(..)"/>
                </transform:otherwise>
            </transform:choose>
        </transform:variable>
        <td valign="top">
           <xsl:value-of select="$root_or_name"/>
        </td>
        <td valign="top">
            <xsl:value-of select="position()"/> of <xsl:value-of select="last()"/>
        </td>
        <td valign="top">
           <xsl:value-of select="namespace-uri()"/>
        </td>
        <td>
            <xsl:for-each select="namespace::*">
                <xsl:value-of select="."/><br />
            </xsl:for-each>
        </td>
    </tr>
    <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Below, notice that in the declaration of the variable $root_or_name in the XSLT file, the prefix associated with the XSLT namespace is changed from xsl: to transform:.

The namespace URI for each element whose name is prefixed with transform: rather than the more conventional xsl: (within the <transform:variable> element's scope) is the same as the namespace URI for all other XSLT elements in the style sheet. Because the xsl: prefix is in scope throughout the entire style sheet, within the <transform:variable> element we can use it (as with the <xsl:when>) instead of transform:.

Processor Output

A portion of the XSLT processor output is shown here, with line breaks added.

<?xml version="1.0" encoding="UTF-16"?>
<html xmlns="http://www.w3.org/TR/REC-html40">
<body>
<table border="1">
<tr style="background-color: silver">
<th>Child Name</th>
<th>Parent</th>
<th>Child #</th>
<th>Namespace URI</th>
<th>Namespace(s) in Scope</th>
</tr>
<tr>
<td valign="top">xsl:stylesheet</td>
<td valign="top">--ROOT--</td>
<td valign="top">2 of 2</td>
<td valign="top">http://www.w3.org/1999/XSL/Transform</td>
<td>http://www.w3.org/XML/1998/namespace
<br />http://www.w3.org/1999/XSL/Transform
<br />http://www.w3.org/TR/REC-html40
<br /></td>
</tr>
<tr>
<td valign="top">xsl:template</td>
<td valign="top">xsl:stylesheet</td>
<td valign="top">1 of 3</td>
<td valign="top">http://www.w3.org/1999/XSL/Transform</td>
...
</table>
</body></html>


Changing Namespace Aliases Programmatically

This section covers the following:

  • Why Namespace Prefix Operations Require Special Handling
  • Manipulating Namespace Prefixes Using <xsl:namespace-alias>
  • Applying a Namespace-Aliasing Style Sheet in Internet Explorer


Why Namespace Prefix Operations Require Special Handling

A special complication arises when the result tree itself is to contain elements from the XSLT namespace — that is, when using XSLT to generate a style sheet.

Consider the case of the XSLT style sheet above (ns_decl.xsl in Example of Declaring Namespaces in XSLT). It contains a mixture of element names — some with the xsl: prefix, some with the transform: prefix, and some (the HTML element names) with no prefix at all.

Now, imagine that you want to create a new style sheet, functionally identical to ns_decl.xsl, but with all the element names that are prefixed transform: changed to use the more conventional xsl:. How would you go about this?

Functionally, XSLT code necessary to modify ns_decl.xsl in this way might perform the following steps for all nodes in the source style sheet:

  1. If the element being processed is <transform:variable>, instantiate in the result tree an <xsl:variable> element instead.
  2. If the element being processed is <transform:choose>, instantiate in the result tree an <xsl:choose> element instead.
  3. If the element being processed is <transform:otherwise>, instantiate in the result tree an <xsl:otherwise> element instead.
  4. If the element being processed is <transform:value-of>, instantiate in the result tree an <xsl:value-of> element instead.
  5. Otherwise, simply copy the element to the result tree unchanged.

Thus, you might think, a style sheet to apply the necessary changes to ns_decl.xsl might look like the following (items to be instantiated in the result tree are highlighted):

XSLT File (ns_decltest.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<!-- For all nodes in the source style sheet -->
<xsl:template match="/ | @* | node()">
    <xsl:choose>

        <!-- 1: If the node name is transform:variable -->
        <xsl:when test="name()='transform:variable'">
            <xsl:variable name="root_or_name">
                <xsl:apply-templates select="node()"/>
            </xsl:variable>
        </xsl:when>

        <!-- 2: If the node name is transform:otherwise -->
        <xsl:when test="name()='transform:otherwise'">
            <xsl:otherwise>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:otherwise>
        </xsl:when>

        <!-- 3: If the node name is transform:choose... -->
        <xsl:when test="name()='transform:choose'">
            <xsl:choose>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:choose>
        </xsl:when>

        <!-- 4: If the node name is transform:value-of... -->
        <xsl:when test="name()='transform:value-of'">
            <xsl:value-of>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:value-of>
        </xsl:when>

        <!-- 5: In all other cases... -->
        <xsl:otherwise>
            <!-- Copy the node and its children to the result tree -->
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

The problem with this solution is that the XSLT processor cannot determine that the code for instantiating content in the result tree is not code meant for its own processing. Essentially, mapping the xsl: prefix to the XSLT namespace URI prevents the processor from seeing this result-tree content as anything other than XSLT code to be parsed and executed.

Indeed, if you apply this style sheet to ns_decl.xsl, Internet Explorer displays an error message:

Keyword xsl:otherwise may not be used here.

This results from Step 2 in the code. The processor thinks you're trying to use the <xsl:otherwise> element as a child of the <xsl:when> — which is illegal XSLT — and rejects it.

Note The processor does not flag Step 1 as an error, but step 1 still does not do what we want it to do — that is, put an <xsl:variable> element in the result tree. However, it is not a violation of XSLT syntax and structure, so no error is produced.


Manipulating Namespace Prefixes Using <xsl:namespace-alias>

To put XSLT code into the result tree:

  1. Create a completely different namespace prefix, assigned to a different namespace URI.
  2. Instruct the XSLT processor on output to replace all occurrences of the newly-created namespace prefix with the conventional xsl:.
  3. Replace all element names meant for output, rather than processing, so that they use the new namespace prefix.

We'll work with a copy of ns_decl.xsl for this, called ns_decl_alias.xsl (shown in Sample XSL File for Changing Namespace Aliases). The style sheet used to convert all occurrences of the transform: prefix to xsl: in ns_decl_alias.xsl is called transform2xsl.xsl; it is an enhanced version of the style sheet whose code was shown above. The final version of transform2xsl.xsl is shown in Sample XSLT File (transform2xsl.xsl).

Step 1: Creating the new namespace prefix

The <xsl:stylesheet> element of transform2xsl.xsl looks like this, originally:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

We'll use a namespace prefix of xslTemp: for all XSLT elements we want to put into the result tree (rather than to be processed). The URI associated with this prefix can be any legitimate string of a URI form; its actual value doesn't matter, as long as it won't be confused with any other namespace URIs in the style sheet. Thus, we end up with something like the following:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xslTemp="temporary.xsl">
Note Again, notice that it is important not just to use a different prefix, but also to connect it to a namespace URI which won't be recognized by the XSLT processor.

Step 2: Asserting the namespace alias

To instruct the XSLT processor that all occurrences of the xslTemp: prefix should be changed, on output, to xsl:, use the top-level empty element <xsl:namespace-alias>. Its syntax is:

<xsl:namespace-alias
stylesheet-prefix="prefixhere"
result-prefix="prefixoutput"/>

where:

  • prefixhere is the prefix used locally, within this style sheet; and
  • prefixoutput is the prefix you want to replace prefixhere with, in the result tree.

In our case, we'll want all occurrences of the xslTemp: prefix in this style sheet to be replaced with xsl: in the result tree. So our <xsl:namespace-alias> element looks like this:

<xsl:namespace-alias
    stylesheet-prefix="xslTemp"
    result-prefix="xsl"/>

Step 3: Using the temporary prefix

Our original version of the transform2xsl.xsl style sheet has four points (highlighted, and numbered 1 through 4 in the comments above) at which we need to replace what look like XSLT instructions with result-tree content. After replacing the xsl: namespace prefixes as needed, this section of transform2xsl.xsl now looks like the following:

Snippet from XSLT File transform2xsl.xsl

        <!-- 1: If the node name is transform:variable -->
        <xsl:when test="name()='transform:variable'">
            <xslTemp:variable name="root_or_name">
                <xsl:apply-templates select="node()"/>
            </xslTemp:variable>
        </xsl:when>

        <!-- 2: If the node name is transform:otherwise -->
        <xsl:when test="name()='transform:otherwise'">
            <xslTemp:otherwise>
                <xsl:apply-templates select="@* | node()"/>
            </xslTemp:otherwise>
        </xsl:when>

        <!-- 3: If the node name is transform:choose... -->
        <xsl:when test="name()='transform:choose'">
            <xslTemp:choose>
                <xsl:apply-templates select="@* | node()"/>
            </xslTemp:choose>
        </xsl:when>

        <!-- 4: If the node name is transform:value-of... -->
        <xsl:when test="name()='transform:value-of'">
            <xslTemp:value-of>
                <xsl:apply-templates select="@* | node()"/>
            </xslTemp:value-of>
        </xsl:when>
Note The fifth step from the original version of transform2xsl.xsl does not need any changes. We want the <xsl:copy-of> element in that step to be executed, not to be placed in the result tree, so its xsl: prefix should not be changed to xslTemp:.

See Also

xsl:namespace-alias Element


Applying a Namespace-Aliasing Style Sheet in Internet Explorer

Because Internet Explorer does not make the result tree of a transformation available directly, you may wonder how to apply the generated or (in this case) modified style sheet to an XML document.

To do so, use script, rather than a simple <?xml-stylesheet> processing instruction, to apply the "invisible" style sheet to the XML document. The general steps are:

  1. 0Use the load method to load the style namespace-aliasing style sheet (transform2xsl.xsl in this case) into one object (called objA, for example), and the style sheet to be modified (ns_decl_alias.xsl, shown in Sample XSL File for Changing Namespace Aliases) into another (objB). The document ultimately to be transformed by the modifed version of objB will be loaded into a third object (objC).
  2. Applying objA to objB using the transformNodeToObject method, creating a new "invisible" or virtual style sheet result-tree object (call it objD).
  3. Finally, apply objD to the document itself, objC, using transformNode.

In our case, the objects represented by objB and objC are the same — ns_decl_alias.xsl. So a simple HTML page (transform2xsl.html) to display the final results would look like the following example HTML file, with the code creating the new "virtual" style sheet highlighted.

Example

To view this example, view the HTML file in Internet Explorer.

XSLT File (ns_decl_alias.xsl)

Use ns_decl_alias.xsl (in Sample XSL File for Changing Namespace Aliases).

HTML File (transform2xsl.html)

<html>
<head>
<title>Namespace Aliasing Example</title>
<script language='JScript'>
<!--
function transformIt() {
    // Associate the result tree object with any element(s) whose
    // id attribute is "transformedXSL."
var objWithPrefixes = document.all['transformedXSL'];

// Declare MSXML DOMDocument objects corresponding to:
//   objA - the style sheet transforming all occurrences of
//      the "transform:" prefix to "xsl:" instead
//   objB - the style sheet which needs to be modified using objA
//   objC - the XML document to be transformed by the result of
//      modifying objB using the rules in objA
//   objD - the result of transforming objB with objA
var objA = new ActiveXObject('MSXML2.DOMDocument');
var objB = new ActiveXObject('MSXML2.DOMDocument');
var objC = new ActiveXObject('MSXML2.DOMDocument');
var objD = new ActiveXObject('MSXML2.DOMDocument');

// Load objA with the style sheet used to modify the base style sheet.
objA.load('transform2xsl.xsl');

// Load objB with the base style sheet.
objB.load('ns_decl_alias.xsl');

// Also load objC with the base style sheet (we're going to apply the
// modified style sheet to the original one).
objC.load('ns_decl_alias.xsl');

// Transform the base style sheet (objB), using the rules established by
// the "transform2xsl.xsl" style sheet (objA); this creates a new virtual
// style sheet, objD.
objB.transformNodeToObject(objA, objD);

// Next, apply the transformed base style sheet to itself -- the "XML"
// which for this application we ultimately want to transform.
strResult = objD.transformNode(objC);

// Assign the resulting string to the result tree object's
// innerHTML property, and exit.
objWithPrefixes.innerHTML = strResult;
return true;
}
-->
</script>
<body onload='transformIt()'>
    <h2>Result with Modified Prefixes</h2>
    <div id='transformedXSL'></div>
</body>
</html>

Formatted Output

The formatted result is nearly identical to the screen captures in the earlier topics in this section (Example of Declaring Namespaces in XSLT). But note the differences:

The original <transform:variable>, <transform:otherwise>, <transform:choose>, and <transform:value-of> elements all have been renamed in the result tree (as seen in the first and second columns) to <xsl:variable>, <xsl:otherwise>, <xsl:choose>, and <xsl:value-of>, respectively.


Sample XSL File for Changing Namespace Aliases

XSLT File (ns_decl_alias.xsl)

<?xml-stylesheet type="text/xsl" href="ns_decl_modify.xsl"?>
<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/TR/REC-html40" >

<xsl:template match="text()"/>

<xsl:template match="/">
   <html>
   <body><table border="1">
      <tr style="background-color: silver">
         <th>Child Name</th>
         <th>Parent</th>
         <th>Child #</th>
         <th>Namespace URI</th>
         <th>Namespace(s) in Scope</th>
      </tr>
      <xsl:apply-templates/>
   </table></body>
   </html>
</xsl:template>

<xsl:template match="*">
   <tr>
      <td valign="top"><xsl:value-of select="name()"/></td>
      <transform:variable name="root_or_name"
         xmlns:transform="http://www.w3.org/1999/XSL/Transform">
         <transform:choose>
            <xsl:when test="name(..)=''">--ROOT--</xsl:when>
            <transform:otherwise>
               <transform:value-of select="name(..)"/>
            </transform:otherwise>
         </transform:choose>
      </transform:variable>
      <td valign="top"><xsl:value-of select="$root_or_name"/></td>
      <td valign="top" nowrap="nowrap">
         <xsl:value-of select="position()"/> of <xsl:value-of select="last()"/>
      </td>
      <td valign="top"><xsl:value-of select="namespace-uri()"/></td>
      <td>
         <xsl:for-each select="namespace::*">
            <xsl:value-of select="."/><br />
         </xsl:for-each>
      </td>
   </tr>
   <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>


Sample XSLT File (transform2xsl.xsl)

XSLT File (transform2xsl.xsl)

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xslTemp="temporary.xsl" >

<xsl:namespace-alias
   stylesheet-prefix="xslTemp"
   result-prefix="xsl"/>

<!-- For all nodes in the source style sheet -->
<xsl:template match="/ | @* | node()">
   <xsl:choose>

      <!-- 1: If the node name is transform:variable -->
      <xsl:when test="name()='transform:variable'">
         <xslTemp:variable name="root_or_name">
            <xsl:apply-templates select="node()"/>
         </xslTemp:variable>
      </xsl:when>

      <!-- 2: If the node name is transform:otherwise -->
      <xsl:when test="name()='transform:otherwise'">
         <xslTemp:otherwise>
            <xsl:apply-templates select="@* | node()"/>
         </xslTemp:otherwise>
      </xsl:when>

      <!-- 3: If the node name is transform:choose... -->
      <xsl:when test="name()='transform:choose'">
         <xslTemp:choose>
            <xsl:apply-templates select="@* | node()"/>
         </xslTemp:choose>
      </xsl:when>

      <!-- 4: If the node name is transform:value-of... -->
      <xsl:when test="name()='transform:value-of'">
         <xslTemp:value-of>
            <xsl:apply-templates select="@* | node()"/>
         </xslTemp:value-of>
      </xsl:when>

      <!-- 5: In all other cases... -->
      <xsl:otherwise>
         <!-- Copy the node and its children to the result tree -->
         <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
         </xsl:copy>
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>

</xsl:stylesheet>


Using msxsl:node-set() to Process Result-Tree Fragments

The msxsl:node-set() function is an XSLT extension function available to developers using the MSXML processor platform. Extension functions are explicitly allowed by the XSLT specification; their purpose is to provide vendor- or platform-specific functionality otherwise not accounted for by the pre-defined XPath and XSLT functions.

This section covers the following:

  • Introduction to Result Tree Fragments
  • Declaring the msxsl: Namespace Prefix
  • Processing a Tree Fragment as a Tree by Using msxsl:node-set()
  • Calculating a Sum of Sums Using msxsl:node-set()

See Also

Using Functions in XPath Expressions


Introduction to Result Tree Fragments

The XPath specification defines four basic data types accessible in XPath location steps, function references, and so on:

  • strings
  • numbers
  • Booleans
  • node-sets

To these basic XPath data types, the XSLT specification adds a fifth: result tree fragments.

A result tree fragment (RTF) is, as the name implies, something that will be placed into the result tree of an XSLT transformation. That is, it is a template to be instantiated in the result tree—specifically, a template instantiated by a non-empty <xsl:variable> or <xsl:param> element. The RTF may or may not be well-formed; it needs only to be well-balanced: each start tag needs to include an end tag, the tags need to be nested properly, and so on. By contrast, the node-set data type always consists of a "tree" with at least a "root element" (which of course may or may not be the document's own root element), beneath which may be many other elements, text, and so on.

The following code fragment from an XSLT stylesheet shows an example of how an <xsl:variable> element can create a non-well-formed but well-balanced RTF:

<xsl:variable name="tree">
<em>Emphasized and <b>bold</b></em> words
</xsl:variable>

The result tree instantiated by this variable will be:

<em>Emphasized and <b>bold</b></em> words

That is, it consists of:

  • A complete <em> element, containing some text and a <b> element, which itself includes some text; and
  • Some trailing text, the string " words".

If you define a variable or parameter which is not empty, it is often desirable to then attempt some operation on the value of the variable or parameter. If you try to do so using built-in XPath and XSLT functions, it will probably not produce the desired result—because those functions are intended to be used with one of the four basic data types, not with result tree fragments.

In the first example above, it might be tempting, for instance, to try to "walk the tree" established by the $tree variable using something like the following XSLT template rule:

XSLT File (rtf.xsl)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="rtf.xsl" ?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:variable name="tree">
<em>Emphasized and <b>bold</b></em> words
</xsl:variable>

<xsl:template match="paragraphtext">
    <table border="1" cellpadding="2" cellspacing="0">
        <tr>
            <th>Node name</th>
            <th>Node type</th>
        </tr>
        <!-- Show document root and each element in $tree variable -->
        <xsl:for-each select="$tree/descendant-or-self::*|$tree">
            <tr>
                <td>
                    <xsl:choose>
                        <xsl:when test="name()=''">
                            (DOC ROOT)
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="name()"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </td>
                <td><xsl:value-of select="."/></td>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

Result

When you use Internet Explorer to view this XSLT file, containing a template rule applied to the above XML result tree fragment, you get an error message:

Reference to variable or parameter 'tree' must evaluate to a node list.

The problem is that XPath and XSLT expressions and functions cannot operate on what is quite likely not a fully-formed sub-tree, including a root element—that is, they cannot operate on result tree fragments.

While this example may seem artificial, you will almost certainly encounter this "not a node list" problem in more real-world situations, such as sorting and grouping.

As a solution to this common problem, Microsoft makes available a special XSLT extension function, msxsl:node-set().

Note A node-set() function is provided by many other XSLT processors as well as the Microsoft implementation. A node-set() function is likely to be added to the core XSLT function library in the next version of that specification.


Declaring the msxsl: Namespace Prefix

To use the msxsl:node-set() function in an XSLT style sheet, you must include a declaration in the style sheet for the msxsl: namespace prefix. Most often, this is done in the style sheet's root <xml:stylesheet> element, as follows:

XSLT File (msxsldecl.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">

<xsl:template match="text()"/>

</xsl:stylesheet>

As with other namespace declarations, the prefix (such as msxsl:) is not important; only the value of the xmlns attribute is important. That value must be "urn:schemas-microsoft-com:xslt" in order to use the Microsoft implementation of the node-set() extension function. For example, you could use this namespace declaration:

xmlns:ms="urn:schemas-microsoft-com:xslt"

or

xmlns:xyz="urn:schemas-microsoft-com:xslt"

as long as all references to the node-set() function appear as ms:node-set() or xyz:node-set(), respectively. Throughout this topic, we have used the msxsl: prefix.

Note The Uniform Resource Identifier (URI) for using Microsoft extensions to core W3C technologies takes the form of a Uniform Resource Name, or URN. This is an accepted alternative to the practice of using Uniform Resource Locators (URLs), as in the declaration for the xmlns:xsl namespace in the above example.
Also note that declaring the msxsl: namespace gives your style sheet access not just to the msxsl:node-set() function, but to other Microsoft extensions such as the <msxsl:script> element.


Processing a Tree Fragment as a Tree by Using msxsl:node-set()

According to the XSLT specification, you can do only two things with a result tree fragment returned as the value of an <xsl:variable> or <xsl:param> element: copy the fragment to the result tree, or treat it as a string.

Often, however, you will want to treat the fragment as a tree or sub-tree in its own right, to enable processing by a further step (such as sorting or accumulating a sum).

To do so:

  1. Declare the msxsl: namespace. For more information, see Declaring the msxsl: Namespace Prefix.
  2. Establish the result tree fragment using a variable or parameter.
  3. Convert the result tree fragment to a node-set using the msxsl:node-set() function.
  4. Use the converted node-set as you would any other, in XPath expressions, function calls, and so on.

A simple example of step #4 would be:

<xsl:value-of select="msxsl:node-set($emprecs)/employee"/>

This treats the variable or parameter called $emprecs as though it were a tree of nodes, and creates in the result tree an instance of the <employee> children of that tree of nodes.


Calculating a Sum of Sums Using msxsl:node-set()

The initial example uses an XML document used in an invoicing application. A common objective in an invoicing application is to show, for each item purchased, the number of items purchased, the unit price, and the total price. This could be accomplished with the XSLT file shown in the initial example below.

This section covers the following:

  • Calculating a Sum of Sums (First Attempt)
  • Calculating a Sum of Sums (Second Attempt)
  • Calculating a Sum of Sums (Final Version)

Initial Example for Sum of Sums

This example generates a table with a header row and one row of data for each item. In subsequent topics, we add sums to this table.

XML File (invoice.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="inv.xsl" ?>
<invoice>
    <item item_num="AX43598">
        <quantity>29</quantity>
        <unit_price>2.00</unit_price>
    </item>
    <item item_num="FH29782">
        <quantity>140</quantity>
        <unit_price>6.50</unit_price>
    </item>
</invoice>

XSLT File (inv.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <table border="1" cellpadding="2" cellspacing="0">
        <tr>
            <th>Item</th>
            <th>Quantity</th>
            <th>Unit Price</th>
            <th>Extended Price</th>
        </tr>
        <xsl:for-each select="invoice/item">
            <tr>
                <td>
                    <xsl:value-of select="@item_num"/>
                </td>
                <td align="right">
                    <xsl:value-of select="quantity"/></td>
                <td align="right">
                    <xsl:value-of select="format-number(unit_price, '#,##0.00')"/>
                </td>
                <td align="right">
                    <xsl:value-of select="format-number(quantity * unit_price, '#,##0.00')"/>
                </td>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

Formatted Output


Calculating a Sum of Sums (First Attempt)

Compared the initial example in Calculating a Sum of Sums Using msxsl:node-set(), a problem arises if you then want to generate a "total extended price" for the invoice—that is, the sum of all extended prices. As a first solution, you would probably try something like the following:

        <tr>
            <th colspan="3">Invoice Total</th>
            <td align="right">
                <xsl:value-of select="format-number(sum(item/quantity * item/unit_price), '#,##0.00')"/>
            </td>
        </tr>

The result of this approach is shown in the following example.

Example

XML File (invoice.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="inv2.xsl" ?>
<invoice>
    <item item_num="AX43598">
        <quantity>29</quantity>
        <unit_price>2.00</unit_price>
    </item>
    <item item_num="FH29782">
        <quantity>140</quantity>
        <unit_price>6.50</unit_price>
    </item>
</invoice>

XSLT File (inv2.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <table border="1" cellpadding="2" cellspacing="0">
        <tr>
            <th>Item</th>
            <th>Quantity</th>
            <th>Unit Price</th>
            <th>Extended Price</th>
        </tr>
        <xsl:for-each select="invoice/item">
            <tr>
                <td>
                    <xsl:value-of select="@item_num"/>
                </td>
                <td align="right">
                    <xsl:value-of select="quantity"/></td>
                <td align="right">
                    <xsl:value-of select="format-number(unit_price, '#,##0.00')"/>
                </td>
                <td align="right">
                    <xsl:value-of select="format-number(quantity * unit_price, '#,##0.00')"/>
                </td>
            </tr>
        </xsl:for-each>
        <tr>
            <th colspan="3">Invoice Total</th>
            <td align="right">
                <xsl:value-of select="format-number(sum(item/quantity * item/unit_price), '#,##0.00')"/>
            </td>
        </tr>
    </table>
</xsl:template>

</xsl:stylesheet>

Result

Internet Explorer (or any other compliant XSLT processor) treats this as an error. The message from Internet Explorer says:

Expression does not return a DOM node. format-number(-->sum(item/quantity * item/unit_price)<--, '#,##0.00')


Calculating a Sum of Sums (Second Attempt)

As a next attempt, let's set up a variable to accumulate and hold the extended price, and try using that variable for the sum operation. The style sheet now looks like this:

<xsl:variable name="ext_price">
    <xsl:for-each select="invoice/item">
        <accum><xsl:value-of select="quantity * unit_price"/></accum>
    </xsl:for-each>
</xsl:variable>

<xsl:template match="/">
...
        <tr>
            <th colspan="3">Total, All Items</th>
            <td align="right">
                <xsl:value-of select="format-number(sum($ext_price/accum), '#,##0.00')"/>
            </td>
        </tr>
...

The result of this attempt is shown in the following example.

Example

XML File (invoice.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="inv3.xsl" ?>
<invoice>
    <item item_num="AX43598">
        <quantity>29</quantity>
        <unit_price>2.00</unit_price>
    </item>
    <item item_num="FH29782">
        <quantity>140</quantity>
        <unit_price>6.50</unit_price>
    </item>
</invoice>

XSLT File (inv3.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:variable name="ext_price">
    <xsl:for-each select="invoice/item">
        <accum><xsl:value-of select="quantity * unit_price"/></accum>
    </xsl:for-each>
</xsl:variable>

<xsl:template match="/">
    <table border="1" cellpadding="2" cellspacing="0">
        <tr>
            <th>Item</th>
            <th>Quantity</th>
            <th>Unit Price</th>
            <th>Extended Price</th>
        </tr>
        <xsl:for-each select="invoice/item">
            <tr>
                <td>
                    <xsl:value-of select="@item_num"/>
                </td>
                <td align="right">
                    <xsl:value-of select="quantity"/></td>
                <td align="right">
                    <xsl:value-of select="format-number(unit_price, '#,##0.00')"/>
                </td>
                <td align="right">
                    <xsl:value-of select="format-number(quantity * unit_price, '#,##0.00')"/>
                </td>
            </tr>
        </xsl:for-each>
        <tr>
            <th colspan="3">Total, All Items</th>
            <td align="right">
                <xsl:value-of select="format-number(sum($ext_price/accum), '#,##0.00')"/>
            </td>
        </tr>
    </table>
</xsl:template>

</xsl:stylesheet>

Result

Now when we try to view our sample document in Internet Explorer, we get another error message:

Reference to variable or parameter 'ext_price' must evaluate to a node list.

Even though our little <accum> element contains numeric data, the XPath sum() function must take a node-set as an argument. To correct the problem, see the next topic.


Calculating a Sum of Sums (Final Version)

To correct the attempt in the previous topic, wrap the reference to the $ext_price variable in the msxsl:node-set() function call, as follows:

        <tr>
            <th colspan="3">Total, All Items</th>
            <td align="right">
                <xsl:value-of select="format-number(sum(msxsl:node-set($ext_price)/accum), '#,##0.00')"/>
            </td>
        </tr>

You also need to declare the msxsl namespace prefix:

<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">

Now the table contains the original data and the total of the extended prices. The finished example is shown below.

For more information about the sum() function, see Using Numeric Functions to Perform Math Operations in XPath.

Example

XML File (invoice.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="invtot.xsl" ?>
<invoice>
    <item item_num="AX43598">
        <quantity>29</quantity>
        <unit_price>2.00</unit_price>
    </item>
    <item item_num="FH29782">
        <quantity>140</quantity>
        <unit_price>6.50</unit_price>
    </item>
</invoice>

XSLT File (invtot.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">

<xsl:variable name="ext_price">
    <xsl:for-each select="invoice/item">
        <accum><xsl:value-of select="quantity * unit_price"/></accum>
    </xsl:for-each>
</xsl:variable>

<xsl:template match="/">
    <table border="1" cellpadding="2" cellspacing="0">
        <tr>
            <th>Item</th>
            <th>Quantity</th>
            <th>Unit Price</th>
            <th>Extended Price</th>
        </tr>
        <xsl:for-each select="invoice/item">
            <tr>
                <td>
                    <xsl:value-of select="@item_num"/>
                </td>
                <td align="right">
                    <xsl:value-of select="quantity"/></td>
                <td align="right">
                    <xsl:value-of select="format-number(unit_price, '#,##0.00')"/>
                </td>
                <td align="right">
                    <xsl:value-of select="format-number(quantity * unit_price, '#,##0.00')"/>
                </td>
            </tr>
        </xsl:for-each>
        <tr>
            <th colspan="3">Total, All Items</th>
            <td align="right">
                <xsl:value-of select="format-number(sum(msxsl:node-set($ext_price)/accum), '#,##0.00')"/>
            </td>
        </tr>
    </table>
</xsl:template>

</xsl:stylesheet>

Formatted Output


Using Named Template Rules in XSLT

As the term implies, an XSLT named template contains a template which can be instantiated in the result tree, and this template is given a name for easy reference elsewhere in the style sheet. The named template is actually instantiated in the result tree only at the point of a corresponding <xsl:call-template> element in a regular template rule.

The following is a simple named template:

<xsl:template name="display_price">
   <xsl:value-of select="@price"/>
</xsl:template>

The following is a template rule that instantiates the named template:

<xsl:template match="/">
    <xsl:call-template name="display_price"/>
</xsl:template>

Note the correspondence between the value of the name attribute of the named template itself, and the value of the name attribute in the <xsl:call-template> element.

The contents of the named template are inserted in the calling template rule, replacing the <xsl:call-template> element.

Named templates have two principal uses:

  • As containers for frequently-used templates
  • As templates whose contents and structures are to be driven depending on some variable set of conditions in the invoking template rules, using parameters

These two uses may or may not be mutually exclusive—a given named template might fulfill one purpose or the other, or both.

This section covers the following:

  • Using Named Templates for Frequently Used Templates
  • Passing Parameters Using Named Templates

This section provides an Initial Example for Named Templates and works toward the final example.

See Also

xsl:template Element | xsl:param Element | xsl:with-param Element | Using XSLT Variables and Parameters | XSLT Utilities and Samples You Can Download


Initial Example for Named Templates

This example creates a standard simple table. The XSLT file does not yet use named templates.

The subsequent topics add named templates, resulting in the Finished Example for Named Templates.

Example

The result is a simple series of headings and tables for the individual regions. It shows data for each sales region but not for all regions together.

XML File (region_qtr.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="region_qtr.xsl" ?>
<sales quarter="2001-01-01">
    <region>
        <name>Northeast</name>
        <manager>Kim Abercrombie</manager>
        <units>9881</units>
        <sales_amt curr="">150680.89</sales_amt>
    </region>
    <region>
        <name>Southeast</name>
        <manager>Jeff D. Henshaw</manager>
        <units>4329</units>
        <sales_amt curr="">67015.48</sales_amt>
    </region>
    <region>
        <name>Southwest</name>
        <manager>Sunil Koduri</manager>
        <units>3543</units>
        <sales_amt curr="">57029.25</sales_amt>
    </region>
    <region>
        <name>Northwest</name>
        <manager>Brad Sutton</manager>
        <units>7569</units>
        <sales_amt curr="">127423.90</sales_amt>
    </region>
</sales>

XSLT File (region_qtr.xsl)

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
    xmlns="http://www.w3.org/TR/REC-html40"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <html>
        <head>
            <title>Quarterly Sales (Quarter Beginning
                <xsl:value-of select="sales/@quarter"/>)
            </title>
            <style type="text/css">
                h1 {background-color: teal;
                    font-family: Tahoma,Verdana,Arial,sans-serif;
                    font-size: 24pt}
                h2 {background-color: yellow;
                    font-family: Tahoma,Verdana,Arial,sans-serif;
                    font-size: 18pt}
                h3 {background-color: white;
                    font-family: Tahoma,Verdana,Arial,sans-serif;
                    font-size: 14pt;
                    font-weight: bold}
                th {background-color: silver;
                    font-family: Tahoma,Verdana,Arial,sans-serif}
                td {background-color: white;
                    font-family: Tahoma,Verdana,Arial,sans-serif}
                .page {width: 75%}
            </style>
        </head>
        <body>
            <div class="page">
                <xsl:apply-templates/>
            </div>
        </body>
    </html>
</xsl:template>

<xsl:template match="sales">
    <h1>Quarterly Sales by Region</h1>
    <h2>Quarter Beginning <xsl:value-of select="@quarter"/></h2>
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="region">
    <h3>
        <xsl:value-of select="name"/> Region
        (Manager: <xsl:value-of select="manager"/>)
    </h3>
    <table width="100%">
        <tr>
            <th># Units</th>
            <th>Qtr Sales Amount</th>
            <th>Amt/Unit</th>
        </tr>
        <tr>
            <td width="33%" align="right">
                <xsl:value-of select="format-number(units, '#,##0')"/>
            </td>
            <td width="33%" align="right">
                <xsl:value-of select="format-number(sales_amt, '#,##0.00')"/>
            </td>
            <td align="right">
                <xsl:value-of select="format-number(sales_amt div units, '#,##0.000')"/>
            </td>
        </tr>
    </table>
</xsl:template>

</xsl:stylesheet>

Formatted Output


Using Named Templates for Frequently Used Templates

To demonstrate using named template as a boilerplate (a frequently used template that is designed to be reusable), we will enhance the region_qtr.xsl style sheet (shown in Initial Example for Named Templates) to display company-wide results as well as the individual regions. The overall results are to be displayed in a manner similar to the individual ones: a level-3 heading, followed by a table. The final result is region_qtr_param.xsl.

The starting example shows data for each sales region but not for all regions together. Here's the relevant portion of the original region_qtr.xsl style sheet from the starting example:

<xsl:template match="sales">
    <h1>Quarterly Sales by Region</h1>
    <h2>Quarter Beginning <xsl:value-of select="@quarter"/></h2>
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="region">
    <h3>
        <xsl:value-of select="name"/> Region
        (Manager: <xsl:value-of select="manager"/>)
    </h3>
    <table width="100%">
        <tr>
            <th width="33%"># Units</th>
            <th width="33%" >Qtr Sales Amount</th>
            <th>Amt/Unit</th>
        </tr>
        <tr>
            <td width="33%" align="right">
                <xsl:value-of select="format-number(units, '#,##0')"/>
            </td>
            <td width="33%" align="right">
                <xsl:value-of select="format-number(sales_amt, '#,##0.00')"/>
            </td>
            <td align="right">
                <xsl:value-of select="format-number(sales_amt div units, '#,##0.000')"/>
            </td>
        </tr>
    </table>
</xsl:template>

The template rule <xsl:template match="sales"> contains an <xsl:apply-templates> statement, which invokes <xsl:template match="region"> to select and process the four <region> elements in region_qtr.xml.

We'll need to add the company-wide table to the template rule for the <sales> element, following the <apply-templates> element. Something like this (the changes are highlighted in bold):

<xsl:template match="sales">
    <h1>Quarterly Sales by Region</h1>
    <h2>Quarter Beginning <xsl:value-of select="@quarter"/></h2>
    <xsl:apply-templates/>
    <h3>Company-Wide Results</h3>
    <table width="100%">
        <tr>
            <th width="33%"># Units</th>
            <th width="33%">Qtr Sales Amount</th>
            <th>Amt/Unit</th>
        </tr>
        <tr>
            [cells for company-wide data]
        </tr>
    </table>
</xsl:template>

The first thing that occurs to us as at this point is that the structure of the first company-wide table row isn't just similar to the corresponding row for the regional tables; it is identical. This is an ideal situation for a reusable named template: a portion of a template, or a complete template, that you want to re-use multiple times in your style sheet.

To set up such a named template, copy the reusable portion into an <xsl:template> rule with a name attribute. In our case, this appears as follows:

<xsl:template name="table_hdgs">
    <tr>
        <th width="33%"># Units</th>
        <th width="33%">Qtr Sales Amount</th>
        <th>Amt/Unit</th>
    </tr>
</xsl:template>
Note The portion to be extracted to a named template must be well-formed. In this case, even though the identical portions of the two template rules include the <table> start tag and the <tr> start tag which follows the first row, the following would not be correct:
<xsl:template name="common_table">
    <table>
    <tr>
            <th width="33%"># Units</th>
            <th width="33%">Qtr Sales Amount</th>
        <th>Amt/Unit</th>
        </tr>
        <tr>
</xsl:template>
This named template would be rejected by the XSLT processor because it is not well-formed.

The second step is to replace, in the style sheet, each occurrence of the extracted code with an <xsl:call-template> element whose name attribute's value matches that of the named template itself.

So our template rules for the <sales> and <region> elements now look like this:

<xsl:template match="sales">
    <h1>Quarterly Sales by Region</h1>
    <h2>Quarter Beginning <xsl:value-of select="@quarter"/></h2>
    <xsl:apply-templates/>
    <h3>Company-Wide Results</h3>
    <table width="100%">
        <xsl:call-template name="common_table"/>
        <tr>
            [cells for company-wide data]
        </tr>
    </table>
</xsl:template>

<xsl:template match="region">
    <h3>
        <xsl:value-of select="name"/> Region
        (Manager: <xsl:value-of select="manager"/>)
    </h3>
    <table width="100%">
        <xsl:call-template name="common_table"/>
        <tr>
            <td width="33%" align="right">
                <xsl:value-of select="format-number(units, '#,##0')"/>
            </td>
            <td width="33%" align="right">
                <xsl:value-of select="format-number(sales_amt, '#,##0.00')"/>
            </td>
            <td align="right">
                <xsl:value-of select="format-number(sales_amt div units, '#,##0.000')"/>
            </td>
        </tr>
    </table>
</xsl:template>

This makes each template rule shorter and easier to understand. And it also simplifies maintenance; to add new columns, for example, or change the formatting, the change has to be done only once to the named template, not once for every occurrence of the reusable, "boilerplate" template.

We continue to build this example in the next topic.


Passing Parameters Using Named Templates

As we continue to build our company-wide table, we continue to observe the ways in which the rest of it resembles the table for each region. A first attempt might look like this:

<xsl:template match="sales">
    <h1>Quarterly Sales by Region</h1>
    <h2>Quarter Beginning <xsl:value-of select="@quarter"/></h2>
    <xsl:apply-templates/>
    <h3>Company-Wide Results</h3>
    <table width="100%">
        <xsl:call-template name="common_table"/>
        <tr>
            <td width="33%" align="right">
                <xsl:value-of select="format-number(sum(region/units), '#,##0')"/>
            </td>
            <td width="33%" align="right">
                <xsl:value-of select="format-number(sum(region/sales_amt), '#,##0.00')"/>
            </td>
            <td align="right">
                <xsl:value-of select="format-number(sum(region/sales_amt) div sum(region/units), '#,##0.000')"/>
            </td>
        </tr>
    </table>
</xsl:template>

In fact, it might seem frustrating that the only differences between this template rule and the one for the <region> element are the data values being plugged into the table. For that matter, even the surrounding <table> element is the same, and the level-3 headings which precede the tables differ only in their contents.

Fortunately, XSLT supplies a device—parameters—which enables us to pass values into a named template for insertion as needed into a common format.

Parameters are passed from the calling template rule to the named template itself using <xsl:with-param> elements in the template rule, and <xsl:param> elements in the named template. Each <xsl:with-param> element is a child of the <xsl:call-template> element; each <xsl:param>, a child of the named template's <xsl:template> element itself.

For instance, a named template to be passed a parameter might look as follows:

<xsl:template name="param_template">
    <xsl:param name="passed_param"/>
    <h1><xsl:value-of select="$passed_param"/></h1>
</xsl:template>

A template rule to pass data to this named template might be:

<xsl:template match="/">
    <xsl:call-template name="param_template">
        <xsl:with-param name="passed_param>Our Company Name</xsl:with-param>
    </xsl:call-template>
</xsl:template>

This template rule passes the string "Our Company Name" to the param_template named template by way of the passed_param parameter. The passed value is then inserted into an <h1> element by the named template, and instantiated in the template rule's result tree.

The <xsl:with-param> and <xsl:param> elements also have an optional select attribute. In the calling template rule, the value of this attribute is an XPath expression relative to the context node at that point. (For more information, see Determining the Context Node.) In the named template, the <xsl:param> element's select attribute supplies a default value if for some reason a calling template rule fails to provide one.

Thus, we can now change our named template as follows. Note in particular the use of passed parameters substituted into the common table structure:

<xsl:template name="common_table">
    <xsl:param name="table_hdg" select="'Default Heading'"/>
    <xsl:param name="units_param" select="'Default Units'"/>
    <xsl:param name="amt_param" select="'Default Amount'"/>
    <h3><xsl:value-of select="$table_hdg"/></h3>
    <table width="100%">
        <tr>
            <th width="33%"># Units</th>
            <th width="33%">Qtr Sales Amount</th>
            <th>Amt/Unit</th>
        </tr>
        <tr>
            <td width="33%" align="right">
                <xsl:value-of select="format-number($units_param, '#,##0')"/>
            </td>
            <td width="33%" align="right">
                <xsl:value-of select="format-number($amt_param, '#,##0.00')"/>
            </td>
            <td align="right">
                <xsl:value-of select="format-number($amt_param div $units_param, '#,##0.000')"/>
            </td>
        </tr>
    </table>
</xsl:template>

The template rules for the <sales> and <region> elements are now shorter, as follows:

<xsl:template match="sales">
    <h1>Quarterly Sales by Region</h1>
    <h2>Quarter Beginning <xsl:value-of select="@quarter"/></h2>
    <xsl:apply-templates/>
    <xsl:call-template name="common_table">
        <xsl:with-param name="table_hdg" select="'Company-Wide Results'"/>
        <xsl:with-param name="units_param" select="sum(region/units)"/>
        <xsl:with-param name="amt_param" select="sum(region/sales_amt)"/>
    </xsl:call-template>
</xsl:template>

<xsl:template match="region">
    <xsl:call-template name="common_table">
        <xsl:with-param name="table_hdg">
            <xsl:value-of select="name"/> Region
            (Manager: <xsl:value-of select="manager"/>)
        </xsl:with-param>
        <xsl:with-param name="units_param" select="units"/>
        <xsl:with-param name="amt_param" select="sales_amt"/>
    </xsl:call-template>
</xsl:template>
Note When passing string values to named templates, as in the select attribute of the <xsl:with-param name="table_hdg" select="'Company-Wide Results'"/> code in the <sales> template rule above, be sure to enclose the string value in internal quotation marks. Otherwise, the XPath expression is evaluated as if it refers to a child of the context node at that point.

Although this example simply passes parameters for display, note that you can also use them to control optional processing in the named template. For instance, we could insert some extra spacing and a horizontal rule into the named template, for display just before the company-wide results, using an <xsl:if> element as follows:

<xsl:if test="$table_hdg='Company-Wide Results'">
    <p />
    <hr />
</xsl:if>

The resulting finished example is shown in the next topic.


Finished Example for Named Templates

This finished example is based on the Initial Example for Named Templates, with named templates added from the above topics.

Example

The result shows the completed company-wide results as well as some of the regional results.

XML File (region_qtr.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="region_qtr_param.xsl" ?>
<sales quarter="2001-01-01">
    <region>
        <name>Northeast</name>
        <manager>Kim Abercrombie</manager>
        <units>9881</units>
        <sales_amt curr="">150680.89</sales_amt>
    </region>
    <region>
        <name>Southeast</name>
        <manager>Jeff D. Henshaw</manager>
        <units>4329</units>
        <sales_amt curr="">67015.48</sales_amt>
    </region>
    <region>
        <name>Southwest</name>
        <manager>Sunil Koduri</manager>
        <units>3543</units>
        <sales_amt curr="">57029.25</sales_amt>
    </region>
    <region>
        <name>Northwest</name>
        <manager>Brad Sutton</manager>
        <units>7569</units>
        <sales_amt curr="">127423.90</sales_amt>
    </region>
</sales>

XSLT File (region_qtr_param.xsl)

This file, region_qtr_param.xsl, is an expanded version of region_qtr.xsl. This is the result of the above topics.

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/TR/REC-html40">

<!-- Template rule for document root -->
<xsl:template match="/">
   <html>
      <head>
         <title>Quarterly Sales (Quarter Beginning
            <xsl:value-of select="sales/@quarter"/>)
         </title>
         <style type="text/css">
            h1 {background-color: teal;
               font-family: Tahoma,Verdana,Arial,sans-serif;
               font-size: 24pt}
            h2 {background-color: yellow;
               font-family: Tahoma,Verdana,Arial,sans-serif;
               font-size: 18pt}
            h3 {background-color: white;
               font-family: Tahoma,Verdana,Arial,sans-serif;
               font-size: 14pt;
               font-weight: bold}
            th {background-color: silver;
               font-family: Tahoma,Verdana,Arial,sans-serif}
            td {background-color: white;
               font-family: Tahoma,Verdana,Arial,sans-serif}
            .page {width: 75%}
         </style>
      </head>
      <body>
         <div class="page">
            <xsl:apply-templates/>
         </div>
      </body>
   </html>
</xsl:template>

<!-- Named template for constructing sales results headings and tables -->
<xsl:template name="common_table">
   <xsl:param name="table_hdg" select="'Default Heading'"/>
   <xsl:param name="units_param" select="'Default Units'"/>
   <xsl:param name="amt_param" select="'Default Amount'"/>
   <xsl:if test="$table_hdg='Company-Wide Results'">
      <p />
      <hr />
   </xsl:if>
   <h3><xsl:value-of select="$table_hdg"/></h3>
   <table width="100%">
      <tr>
         <th width="33%"># Units</th>
         <th width="33%">Qtr Sales Amount</th>
         <th>Amt/Unit</th>
      </tr>
      <tr>
         <td width="33%" align="right">
            <xsl:value-of select="format-number($units_param, '#,##0')"/>
         </td>
         <td width="33%" align="right">
            <xsl:value-of select="format-number($amt_param, '#,##0.00')"/>
         </td>
         <td align="right">
            <xsl:value-of select="format-number($amt_param div $units_param, '#,##0.000')"/>
         </td>
      </tr>
   </table>
</xsl:template>

<!-- Template rule for root <sales> element -->
<xsl:template match="sales">
   <h1>Quarterly Sales by Region</h1>
   <h2>Quarter Beginning <xsl:value-of select="@quarter"/></h2>
   <xsl:apply-templates/>
   <xsl:call-template name="common_table">
      <xsl:with-param name="table_hdg" select="'Company-Wide Results'"/>
      <xsl:with-param name="units_param" select="sum(region/units)"/>
      <xsl:with-param name="amt_param" select="sum(region/sales_amt)"/>
   </xsl:call-template>
</xsl:template>

<!-- Template rule for each <region> element -->
<xsl:template match="region">
   <xsl:call-template name="common_table">
      <xsl:with-param name="table_hdg">
         <xsl:value-of select="name"/> Region
         (Manager: <xsl:value-of select="manager"/>)
      </xsl:with-param>
      <xsl:with-param name="units_param" select="units"/>
      <xsl:with-param name="amt_param" select="sales_amt"/>
   </xsl:call-template>
</xsl:template>

</xsl:stylesheet>

Formatted Output

A portion of the result is shown here.


Inserting Automatic Numbering Using XSLT

XSLT provides various facilities enabling you to number portions of your output, such as in a numbered list of items or chapter/section numbers. This topic covers these facilities, as well as controlling the way in which such numbers can be formatted.

This section covers the following:

  • Inserting Automatic Numbering Using position()
  • Inserting Automatic Numbering Using <xsl:number>

The topics in this section use cardgame.xml (in Inserting Automatic Numbering Using position()), which represents the playing cards dealt in a card game with two players. Each player receives five cards at first, and in the second hand of the game may exchange up to three cards for new cards.

Two hands are dealt. During the first hand, Jack receives the Queen of Clubs, Ace of Spades, and so on, while Jill receives the 5 of Diamonds, 5 of Spades, and so on. In the second hand, Jack trades in three cards (look at the replace attributes to see which ones), and Jill only one.

The hand each player is dealt includes one or more <tell> elements. (A "tell" in card games is a player's reaction—often unconscious—to the cards they have received.)

See Also

position Function | xsl:number Element | xsl:decimal-format Element | format-number Function | Context and Navigation in XPath


Inserting Automatic Numbering Using position()

This example and the following topics use XSLT to display a two-player, two-hand card game as an HTML document.

Note the use of the position() function. This XPath function simply returns the number of the current node within whatever node-set is being processed. Because the node-set established by the template rule (match="hand") contains all <hand> elements in the document, the output will simply be numbered from 1 to 2, in document order.

Example

XML File (cardgame.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="cardgame_orig.xsl"?>
<cardgame>
    <hand>
        <player name="Jack">
            <card dealtID="card01">
                <rank>Q</rank><suit>Clubs</suit>
            </card>
            <card dealtID="card02">
                <rank>A</rank><suit>Spades</suit>
            </card>
            <card dealtID="card03">
                <rank>10</rank><suit>Hearts</suit>
            </card>
            <tell>twitches nervously</tell>
            <card dealtID="card04">
                <rank>8</rank><suit>Clubs</suit>
            </card>
            <card dealtID="card05">
                <rank>4</rank><suit>Spades</suit>
            </card>
            <tell>squints</tell>
        </player>
        <player name="Jill">
            <card dealtID="card06">
                <rank>5</rank><suit>Diamonds</suit>
            </card>
            <card dealtID="card07">
                <rank>5</rank><suit>Spades</suit>
            </card>
            <card dealtID="card08">
                <rank>6</rank><suit>Clubs</suit>
            </card>
            <card dealtID="card09">
                <rank>6</rank><suit>Spades</suit>
            </card>
            <card dealtID="card10">
                <rank>10</rank><suit>Diamonds</suit>
            </card>
            <tell>grins</tell>
        </player>
    </hand>
    <hand>
        <player name="Jack">
            <card dealtID="card11" replace="card03">
                <rank>4</rank><suit>Diamonds</suit>
            </card>
            <tell>mutters, "Uh-oh..."</tell>
            <card dealtID="card12" replace="card04">
                <rank>K</rank><suit>Spades</suit>
            </card>
            <card dealtID="card13" replace="card05">
                <rank>7</rank><suit>Spades</suit>
            </card>
            <tell>tugs at left ear</tell>
        </player>
        <player name="Jill">
            <card dealtID="card14" replace="card10">
                <rank>K</rank><suit>Diamonds</suit>
            </card>
            <tell>sips her drink</tell>
        </player>
    </hand>
</cardgame>

XSLT File (cardgame_orig.xsl)

The first version of the XSLT style sheet simply numbers the hands, using a template rule for the <hand> element:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
    xmlns="http://www.w3.org/TR/REC-html40"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- set up the HTML page and table styles -->
<xsl:template match="/">
    <html>
        <head>
            <title>Card Game</title>
            <style type="text/css">
                h1 {background-color: gold;
                    font-family: Tahoma,Verdana,Arial,sans-serif;
                    font-size: 24pt}
                h2 {background-color: yellow;
                    font-family: Tahoma,Verdana,Arial,sans-serif;
                    font-size: 18pt}
                h3 {background-color: white;
                    font-family: Tahoma,Verdana,Arial,sans-serif;
                    font-size: 14pt;
                    font-weight: bold}
                th {background-color: silver;
                    font-family: Tahoma,Verdana,Arial,sans-serif}
                td {background-color: white;
                    font-family: Tahoma,Verdana,Arial,sans-serif}
                .page {width: 75%}
                .tell {font-weight: bold}
            </style>
        </head>
        <body>
            <div class="page">
                <xsl:apply-templates/>
            </div>
        </body>
    </html>
</xsl:template>

<!-- suppress <tell> elements -->
<xsl:template match="tell"/>

<xsl:template match="hand">
    <h1>Hand #<xsl:value-of select="position()"/></h1>
    <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

Formatted Output


Inserting Automatic Numbering Using <xsl:number>

The <xsl:number> element is useful for generating hierarchical strings of numbers which indicate the depth to which a particular portion of a document is nested. For example, a hypothetical document outline might appear as:

I. Major Heading #1

I.A. First sub-heading under Major Heading #1

I.A.1. ...

I.A.2. ...

I.B. Second sub-heading under Major Heading #1

II. Major heading #2

and so on.

You can think of cardgame.xml (in Inserting Automatic Numbering Using position()) as a hierarchy which conveniently lends itself to this sort of numbering. Within each hand, there's a level representing the player; and for each player, there are any number of cards dealt (up to five). We've saved ourselves a little bit of work because the hands themselves have already been numbered using the position() function, but now let's use <xsl:number> for numbering the players and the cards dealt to them.

Here's the general form of an <xsl:number> element's start tag:

<xsl:number
    level="depthofnumbering"
    count="pattern"
    from="pattern"
    value="expression"
    format="formatspec"
    lang="langcode"
    letter-value="alphaortrad"
    grouping-separator="character"
    grouping-size="number" >

All of the attributes are optional. The ones we'll be concerned with in this section (and the ones you will probably use most often) are level, count, and format.

Used without any attributes at all, <xsl:number> functions the same way as the position() function does, as demonstrated earlier.

Thus, this template rule, added to our existing style sheet (cardgame_orig.xsl, in Inserting Automatic Numbering Using position()):

<xsl:template match="player">
    <h2>
        Player <xsl:number/>:
        <xsl:value-of select="@name"/>
    </h2>
    <xsl:apply-templates/>
</xsl:template>

simply displays the player's positions within each hand, as in the level-2 headings shown here:

We want to number the players a little more carefully, though, using a combination of the hand number and the position of the <player> element within that hand. We can use <xsl:number> with level="multiple", level="single", or level="any".

This section continues with the following topics:

  • Using level='multiple' for Numbering
  • Using level='single' for Numbering
  • Using level='any' for Numbering


Using level='multiple' for Numbering

In this first solution, we add to the <xsl:number> element above the level, format, and count attributes. These attributes are added to our existing style sheet (cardgame_orig.xsl, in Inserting Automatic Numbering Using position()).

<xsl:template match="player">
    <h2>
        Player
        <xsl:number
            level="multiple"
            format="1.1"
            count="hand | player"/>:
        <xsl:value-of select="@name"/>
    </h2>
    <xsl:apply-templates/>
</xsl:template>

The level attribute, with the value "multiple," indicates that this will be a hierarchical number; the format attribute says that the hierarchy will be represented as a string of period-delimited integers (such as 1.1, 1.2, 2.1, and so on). As for the count attribute, it includes a pipe (|)-delimited list of elements along the ancestor-or-self:: axis which are to be used in determining the number to be displayed.

Output from this version of the style sheet now appears as follows:

Note how the numbering of each player now follows the general format:

handnumber.playernumber

rather than just the player number alone.

Finally, we're going to add the <xsl:template match="card"> template rule to process the individual cards dealt in each hand. Once again, we'll use <xsl:number> to number them according to their sequence within each hand dealt, and within each <player> element to which the <card> elements belong. One difference: we'll change the formatting required for "card numbers" within each hand/player hierarchy, so that each card will be represented with two digits instead of one. For instance, a card might be represented as:

2.1.04

which would mean "the fourth card dealt to player #1 in hand #2."

We'll also add some code to generate a <table> element and table headings for each group of cards. Our two template rules in cardgame_orig.xsl now look like this:

<xsl:template match="player">
    <h2>
        Player
        <xsl:number
            level="multiple"
            format="1.1"
            count="hand | player"/>:
        <xsl:value-of select="@name"/>
    </h2>
    <table width="75%">
        <tr>
            <th>Card #</th>
            <th>Rank/Suit</th>
            <th>Replaces</th>
        </tr>
        <xsl:apply-templates/>
    </table>
</xsl:template>

<xsl:template match="card">
    <tr>
        <td align="center" width="30%">
            <xsl:number
                level="multiple"
                format="1.1.01"
                count="hand | player | card"/>
        </td>
        <td width="40%">
            <xsl:value-of select="rank"/>
            <xsl:text> of </xsl:text>
            <xsl:value-of select="suit"/>
        </td>
        <td>
            <xsl:choose>
                <xsl:when test="@replace">
                    <xsl:value-of select="preceding::card[@dealtID=current()/@replace]/rank"/>
                    of <xsl:value-of select="preceding::card[@dealtID=current()/@replace]/suit"/>
                </xsl:when>
                <xsl:otherwise>--</xsl:otherwise>
            </xsl:choose>
        </td>
    </tr>
</xsl:template>
Note The values inserted into the last column (headed "Replaces") use a complex pair of XPath expressions. Translated, these expressions obtain (for each <card> element) the rank and suit of a preceding <card> element whose dealtID attribute matches the replace attribute of the current <card> element. If there is no such preceding <card>, this table cell simply contains a pair of hyphens (--).

A portion of the results when viewed in Internet Explorer looks like this:


Using level='single' for Numbering

The <xsl:number> examples above use the level="multiple" attribute to assign a series of hierarchical number strings such as 1.1.01, 1.1.02, and so on.

The level attribute can also take the values 'single' and 'any'. These are used to sequentially number elements either at the same level in the document tree, or across all levels, respectively.

To demonstrate the effects of these two values, we're going to set up a non-empty template rule for the <tell> elements in our sample XML document.

Here's how the template rule looks for level="single":

<xsl:template match="tell">
    <tr>
        <td colspan="3" align="center" class="tell">
            (Reaction #<xsl:number level="single" count="tell"/>:
            <xsl:value-of select="../@name"/>
            <xsl:text> </xsl:text>
            <xsl:value-of select="."/>)
        </td>
    </tr>
</xsl:template>

The value "single" tells the XSLT processor to generate a sequential number which cycles through the elements whose names match the value of the count attribute, considering them a family as it were, and to start the numbering over again when a new family begins.

Look at the formatted output below to see this effect; note the numbering assigned to the "reactions" of Jack and Jill as the cards are dealt.

The numbering generated from the <tell> elements begins anew with each player, so Jack's reactions are numbered 1 and 2, and Jill's reactions are numbered starting at 1 again.


Using level='any' for Numbering

Now we'll substitute the value "any":

<xsl:template match="tell">
    <tr>
        <td colspan="3" align="center" class="tell">
            (Reaction #<xsl:number level="any" count="tell"/>:
            <xsl:value-of select="../@name"/>
            <xsl:text> </xsl:text>
            <xsl:value-of select="."/>)
        </td>
    </tr>
</xsl:template>

The value "any" instructs the XSLT processor to number the indicated element sequentially no matter at what level—in what "family"—it appears. Jack's reactions during the first hand are still numbered 1 and 2, while Jill's first reaction is now #3 in the game as a whole. The results are shown in Example of Automatic Numbering with <xsl:number>.


Example of Automatic Numbering with <xsl:number>

Example

This is the final example produced by the topics about automatic numbering with <xsl:number>.

XML File (cardgame.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="cardgame_xslnum.xsl"?>
<cardgame>
    <hand>
        <player name="Jack">
            <card dealtID="card01">
                <rank>Q</rank><suit>Clubs</suit>
            </card>
            <card dealtID="card02">
                <rank>A</rank><suit>Spades</suit>
            </card>
            <card dealtID="card03">
                <rank>10</rank><suit>Hearts</suit>
            </card>
            <tell>twitches nervously</tell>
            <card dealtID="card04">
                <rank>8</rank><suit>Clubs</suit>
            </card>
            <card dealtID="card05">
                <rank>4</rank><suit>Spades</suit>
            </card>
            <tell>squints</tell>
        </player>
        <player name="Jill">
            <card dealtID="card06">
                <rank>5</rank><suit>Diamonds</suit>
            </card>
            <card dealtID="card07">
                <rank>5</rank><suit>Spades</suit>
            </card>
            <card dealtID="card08">
                <rank>6</rank><suit>Clubs</suit>
            </card>
            <card dealtID="card09">
                <rank>6</rank><suit>Spades</suit>
            </card>
            <card dealtID="card10">
                <rank>10</rank><suit>Diamonds</suit>
            </card>
            <tell>grins</tell>
        </player>
    </hand>
    <hand>
        <player name="Jack">
            <card dealtID="card11" replace="card03">
                <rank>4</rank><suit>Diamonds</suit>
            </card>
            <tell>mutters, "Uh-oh..."</tell>
            <card dealtID="card12" replace="card04">
                <rank>K</rank><suit>Spades</suit>
            </card>
            <card dealtID="card13" replace="card05">
                <rank>7</rank><suit>Spades</suit>
            </card>
            <tell>tugs at left ear</tell>
        </player>
        <player name="Jill">
            <card dealtID="card14" replace="card10">
                <rank>K</rank><suit>Diamonds</suit>
            </card>
            <tell>sips her drink</tell>
        </player>
    </hand>
</cardgame>

XSLT File (cardgame_xslnum.xsl)

This is the final version of the XSLT file for the topics about automatic numbering with <xsl:number>.

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/TR/REC-html40">

<!-- Template rule for document root -->
<xsl:template match="/">
    <html>
        <head>
            <title>Card Game</title>
            <style type="text/css">
                h1 {background-color: gold;
                    font-family: Tahoma,Verdana,Arial,sans-serif;
                    font-size: 24pt}
                h2 {background-color: yellow;
                    font-family: Tahoma,Verdana,Arial,sans-serif;
                    font-size: 18pt}
                h3 {background-color: white;
                    font-family: Tahoma,Verdana,Arial,sans-serif;
                    font-size: 14pt;
                    font-weight: bold}
                th {background-color: silver;
                    font-family: Tahoma,Verdana,Arial,sans-serif}
                td {background-color: white;
                    font-family: Tahoma,Verdana,Arial,sans-serif}
                .page {width: 75%}
                .tell {font-weight: bold}
            </style>
        </head>
        <body>
            <div class="page">
                <xsl:apply-templates/>
            </div>
        </body>
    </html>
</xsl:template>

<xsl:template match="hand">
    <h1>Hand #<xsl:value-of select="position()"/></h1>
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="player">
    <h2>
        Player
        <xsl:number
            level="multiple"
            format="1.1"
            count="hand | player"/>:
        <xsl:value-of select="@name"/>
    </h2>
    <table width="75%">
        <tr>
            <th>Hand.Player.Card</th>
            <th>Rank/Suit</th>
            <th>Replaces</th>
        </tr>
        <xsl:apply-templates/>
    </table>
</xsl:template>

<xsl:template match="card">
    <tr>
        <td align="center" width="30%">
            <xsl:number
                level="multiple"
                format="1.1.01"
                count="hand | player | card"/>
        </td>
        <td width="40%">
            <xsl:value-of select="rank"/>
            <xsl:text> of </xsl:text>
            <xsl:value-of select="suit"/>
        </td>
        <td>
            <xsl:choose>
                <xsl:when test="@replace">
                    <xsl:value-of select="preceding::card[@dealtID=current()/@replace]/rank"/>
                    of <xsl:value-of select="preceding::card[@dealtID=current()/@replace]/suit"/>
                </xsl:when>
                <xsl:otherwise>--</xsl:otherwise>
            </xsl:choose>
        </td>
    </tr>
</xsl:template>

<xsl:template match="tell">
    <tr>
        <td colspan="3" align="center" class="tell">
            (Reaction #<xsl:number level="any" count="tell"/>:
            <xsl:value-of select="../@name"/>
            <xsl:text> </xsl:text>
            <xsl:value-of select="."/>)
        </td>
    </tr>
</xsl:template>

</xsl:stylesheet>

Formatted Output


Importing and Including Style Sheets

XSLT provides the <xsl:import> and <xsl:include> elements for incorporating the content of one style sheet within another. This section covers the following:

  • Initial Example for Importing Style Sheets
  • Using <xsl:include> to Insert an XSLT File
  • Using <xsl:import> to Insert an XSLT File with Lower Precedence
  • Deciding Whether to Import or Include an XSLT File
  • Avoiding Conflicting Rules by Using <xsl:apply-imports>

Using external parsed entities with DTDs

Since XSLT style sheets are XML documents themselves, you can also use XML's own simple facility for incorporating one XML document within another. This facility, the use of external parsed entities, is covered in the XML Programmer's Guide. The advantage of using such entities is that they are not constrained by any of the XSLT-specific rules governing the use of the <xsl:include> and <xsl:import> elements—only by the rules of well-formed XML documents. The drawback of using such entities is that they require the presence of a Document Type Definition (DTD), which will not always be practical or even possible.

See Also

Class Patterns: Using <xsl:import> and <xsl:include>


Initial Example for Importing Style Sheets

Scootney Publishing's line of books covers a broad range of subjects—general fiction, literary fiction, genre fiction (such as science fiction and romance), software and other technical reference books, biography, and home-repair titles. One of the company's most successful ventures has been placing the first chapter or two of each of its books on the company's Web site, as a "teaser" to encourage actual book sales.

Each book's content is represented as XML, and each line of books has its own XSLT stylesheet: each literary novel one way, each reference book another, and so on. This makes it easy to maintain a consistent look-and-feel across the various sections of the Scootney Web site. Unfortunately, their latest title—a novel, Synchronized Jamming—is a weird amalgam of fictional, technical, and other content, marked up using combined elements of several editorial lines.

Example

XML File (jamming.xml)

Here's a brief excerpt from Synchronized Jamming's first chapter. The book's structure is a mix of common elements of fiction, literal HTML code, and musical annotation.

<?xml version="1.0"?>
<?xml:stylesheet type="text/xsl" href="jamming.xsl"?>
<novel copyright="2001" isbn="555000000X">
   <title>Synchronized Jamming</title>
   <author>Kari Hensien</author>
   <chapter number="1">
      <title>The Bleeding Edge</title>
      <epigraph><text>Any sufficiently advanced technology is indistinguishable from noise.</text><author>Canopy Rose</author><source>The Fusion Manifesto</source></epigraph>
      <para>Politics. Technology. Rock'n'roll. All you needed to know about the underground band known as Canopy Rose was right there in the first couple grafs of their so-called "Fusion Manifesto":</para>
      <markup_code><![CDATA[
<html>
<head><title>Fused</title></head>
<body>
<p>Listen. You know as well as we do...</p>
<p>... the sound of one hand jammin':</p>
]]></markup_code>
      <chord duration="4.5" units="seconds" voice="steel" vibrato="on">
         <note>A</note>
         <note>C</note>
      </chord>
      <markup_code><![CDATA[
<p>Welcome to the block party. Welcome to the revolution.</p>
</body>
</html>
]]></markup_code>
   </chapter>
</novel>

XSLT File (jamming.xsl)

The initial version of the XSLT style sheet (jamming.xsl) developed by the Scootney production department covered all the fiction-related markup in Synchronized Jamming. It was derived from the standard fiction.xsl style sheet used for converting novel excerpts to HTML.

The style sheet provides template rules for all the common "fictional content" encountered in this excerpt. Other such content types, like dialogue among characters, may be included in the style sheet later, as they're encountered.

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/TR/REC-html40">

<xsl:template match="novel">
   <html>
      <head>
         <title>Excerpt:
            "<xsl:value-of select="title"/>,"
            by
            <xsl:value-of select="author"/>
         </title>
         <style>
            * {font-family: Arial,Helvetica,Univers,sans-serif}
            pre {font-family: Courier New,Courier,monospace}
         </style>
      </head>
      <body>
         <h2>Excerpt:<br/>
         <em><xsl:value-of select="title"/></em></h2>
         <h3>by <xsl:value-of select="author"/></h3>
         <h6>Copyright <xsl:value-of select="@copyright"/>
            by <xsl:value-of select="author"/></h6>
         <h6>Scootney Publishing / ISBN
            <xsl:value-of select="@isbn"/></h6>
         <hr size="2" width="50%" align="left"/>
         <xsl:apply-templates />
      </body>
   </html>
</xsl:template>

<xsl:template match="novel/title">
</xsl:template>

<xsl:template match="novel/author">
</xsl:template>

<xsl:template match="chapter">
   <div style="width:50%">
      <h2>Chapter <xsl:value-of select="@number"/>:<br/>
         <xsl:value-of select="title"/></h2>
      <xsl:apply-templates/>
   </div>
</xsl:template>

<xsl:template match="chapter/title">
</xsl:template>

<xsl:template match="epigraph">
   <div style="width:50%; float:right; margin:5; padding:5; background-color:silver; border-style:double; border-left-width:0; border-right-width:0">
      <xsl:apply-templates/>
   </div>
</xsl:template>

<xsl:template match="epigraph/text">
   <div>
      <em><value-of select="."/></em>
      <xsl:apply-templates/>
   </div>
</xsl:template>

<xsl:template match="epigraph/author">
   -- <xsl-value-of select="."/>
   <xsl:apply-templates/>
</xsl:template>

<xsl:template match="epigraph/source">
   (<em><xsl:value-of select="."/></em>)
</xsl:template>

<xsl:template match="para">
   <p><xsl:value-of select="."/></p>
</xsl:template>

</xsl:stylesheet>

Formatted Output

The initial XSLT file displays the fiction-related elements' contents, but not those from the computer- and music-related domains.


Using <xsl:include> to Insert an XSLT File

Many programming languages allow you to logically include the contents of one program (or portion of a program) within the scope of another, without the need to physically do so. For instance, the C programming language comes with the option to use a #include directive for this purpose. Web sites developed using Microsoft FrontPage can take advantage of a similar feature, the "Include Page" component, which causes HTML code from one document to be embedded within another.

The XSLT counterpart of this feature is the <xsl:include> element. This is a top-level element within the style sheet—that is, it must be a child of the style sheet's root <xsl:stylesheet> element. The syntax is simple:

<xsl:include href="uri" />

where uri is the Uniform Resource Identifier (URI) of the style sheet to be embedded at that point.

The referenced style sheet must be a valid style sheet itself. That is, it must include a root <xsl:stylesheet> element. With the exception of this root element's start and end tags, the entirety of its content is logically inserted into the including style sheet, just as if the template rules, named templates, variable declarations, and so on were physically included at that point.

Although the <xsl:include> must be a top-level element, there are no restrictions on where it must be placed, among all the style sheet's other top-level elements.

The markup_code.xsl file (shown below) is included into the main XSLT file. To incorporate the important template rule for the processing the <markup_code> elements in jamming.xml (shown in Initial Example for Importing Style Sheets), the fiction group's production department simply added an <xsl:include> element to jamming.xsl:

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/TR/REC-html40">

<xsl:include href="markup_code.xsl"/>

<xsl:template match="novel">
   [and so on]

That saved a few lines of coding, while ensuring that the <markup_code> elements in Synchronized Jamming would be treated the same as those in a real computer reference text. Saving them even more lines of coding was the fact that Scootney's "ScootMusic" line of books had already established a transformation for <chord> elements (chord.xsl), shown in the example below as an imported XSLT file.

A reference to chord.xsl was added to jamming.xsl as follows:

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/TR/REC-html40">

<xsl:include href="markup_code.xsl"/>
<xsl:include href="chord.xsl"/>

<xsl:template match="novel">
...

As a result, the first chapter of Synchronized Jamming displayed in a manner consistent with all three publishing lines, as shown in the formatted result in the example.

To really simplify jamming.xsl, its designers could have simply included not only markup_code.xsl and chord.xsl, but the entire fiction.xsl style sheet from which jamming.xsl is otherwise derived—and then removed all of the specific template rules which jamming.xsl provides. The resulting style sheet in its entirety would look as follows:

Alternative XSLT File (jamming_importonly.xsl)

This file is not used in the full example.

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/TR/REC-html40">

<xsl:include href="markup_code.xsl"/>
<xsl:include href="chord.xsl"/>
<xsl:include href="fiction.xsl"/>

</xsl:stylesheet>

Example

This example builds on the example from Initial Example for Importing Style Sheets.

The fiction-publishing branch of Scootney Publishing asked around and found that a style sheet (markup_code.xsl) had already been established in the computer-reference division for the <markup_code> element, with which they were previously unfamiliar. They also learned that the computer-reference division had broken out all their separate styles into separate style sheet modules such as chord.xsl, which could simply be included in other style sheets as needed.

XML File (jamming.xml)

Use jamming.xml (in Initial Example for Importing Style Sheets) and change the href attribute to reference jamming2.xsl.

Included XSLT File (markup_code.xsl)

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/TR/REC-html40">

<xsl:template match="markup_code">
   <div style="width:75%; margin-left:20; padding:10">
      <pre><xsl:value-of select="."/></pre>
   </div>
</xsl:template>

</xsl:stylesheet>

Included or Imported XSLT File (chord.xsl)

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/TR/REC-html40">

<xsl:template match="chord">
   <div style="width:75%; margin-left:20; padding:10">
      <table border="0">
         <tr>
            <th style="background-color: yellow">
               <xsl:attribute name="colspan"><xsl:value-of select="count(note)"/></xsl:attribute>
               Chord Notes
            </th>
         </tr>
         <tr>
            <xsl:for-each select="note">
               <td><b><xsl:value-of select="."/></b></td>
            </xsl:for-each>
         </tr>
         <tr>
            <td style="background-color: yellow">
               <xsl:attribute name="colspan"><xsl:value-of select="count(note)"/></xsl:attribute>
               Duration:
                  <xsl:value-of select="@duration"/><xsl:text> </xsl:text>
                  <xsl:value-of select="@units"/>
            </td>
         </tr>
         <tr>
            <td style="background-color: yellow">
               <xsl:attribute name="colspan"><xsl:value-of select="count(note)"/></xsl:attribute>
               Voice: <xsl:value-of select="@voice"/>
            </td>
         </tr>
         <tr>
            <td style="background-color: yellow">
               <xsl:attribute name="colspan"><xsl:value-of select="count(note)"/></xsl:attribute>
               Vibrato: <xsl:value-of select="@vibrato"/>
            </td>
         </tr>
      </table>
   </div>
</xsl:template>

</xsl:stylesheet>

XSLT File (jamming2.xsl)

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/TR/REC-html40">

<xsl:include href="markup_code.xsl"/>
<xsl:include href="chord.xsl"/>

<xsl:template match="novel">
   <html>
      <head>
         <title>Excerpt:
            "<xsl:value-of select="title"/>,"
            by
            <xsl:value-of select="author"/>
         </title>
         <style>
            * {font-family: Arial,Helvetica,Univers,sans-serif}
            pre {font-family: Courier New,Courier,monospace}
         </style>
      </head>
      <body>
         <h2>Excerpt:<br/>
         <em><xsl:value-of select="title"/></em></h2>
         <h3>by <xsl:value-of select="author"/></h3>
         <h6>Copyright <xsl:value-of select="@copyright"/>
            by <xsl:value-of select="author"/></h6>
         <h6>Scootney Publishing / ISBN
            <xsl:value-of select="@isbn"/></h6>
         <hr size="2" width="50%" align="left"/>
         <xsl:apply-templates />
      </body>
   </html>
</xsl:template>

<xsl:template match="novel/title">
</xsl:template>

<xsl:template match="novel/author">
</xsl:template>

<xsl:template match="chapter">
   <div style="width:50%">
      <h2>Chapter <xsl:value-of select="@number"/>:<br/>
         <xsl:value-of select="title"/></h2>
      <xsl:apply-templates/>
   </div>
</xsl:template>

<xsl:template match="chapter/title">
</xsl:template>

<xsl:template match="epigraph">
   <div style="width:50%; float:right; margin:5; padding:5; background-color:silver; border-style:double; border-left-width:0; border-right-width:0">
      <xsl:apply-templates/>
   </div>
</xsl:template>

<xsl:template match="epigraph/text">
   <div>
      <em><value-of select="."/></em>
      <xsl:apply-templates/>
   </div>
</xsl:template>

<xsl:template match="epigraph/author">
   -- <xsl-value-of select="."/>
   <xsl:apply-templates/>
</xsl:template>

<xsl:template match="epigraph/source">
   (<em><xsl:value-of select="."/></em>)
</xsl:template>

<xsl:template match="para">
   <p><xsl:value-of select="."/></p>
</xsl:template>

</xsl:stylesheet>

Formatted Output


Using <xsl:import> to Insert an XSLT File with Lower Precedence

In addition to a simple "include" mechanism, the XSLT standard also provides a more advanced "import" feature: the <xsl:import> element.

The <xsl:import> element resembles the <xsl:include> in many respects. It, too, is an empty, top-level element, and its syntax is identical:

<xsl:import href="uri"/>

where uri is the Uniform Resource Identifier (URI) of another style sheet whose contents are to be logically included within the main style sheet.


Deciding Whether to Import or Include an XSLT File

All <xsl:import> elements must appear as the first top-level elements in the importing style sheet. By contrast, <xsl:include> elements may appear anywhere at all in the including style sheet.

The main difference between <xsl:import> and <xsl:include> is that the template rules and other top-level elements embedded with <xsl:import> are processed according to the explicit rules of import precedence. This enables you to control the ways in which conflicting or overlapping styles are applied, in a predictable fashion. Any template rules imported into a style sheet have a lower import precedence than those physically residing in that style sheet; template rules included in a style sheet have the same import precedence as those in the including style sheet.

Consider a style sheet—call it main.xsl—within which we would like to logically incorporate the contents of another style sheet, sub_1.xsl. Furthermore, sub_1.xsl will incorporate sub_2.xsl. The main.xsl style sheet has a template rule for processing an <a> element; sub_1.xsl, a template rule for processing a <b>; and sub_2.xsl, template rules for both an <a> element and a <b> element.

Whether using <xsl:include> or <xsl:import>, the general logical structure of the three style sheets might be represented as follows:

main.xsl:

sub_1.xsl:

template rule for <b>

sub_2.xsl:

template rule for <a>

template rule for <b>

main.xsl's own template rule for <a>

If main.xsl includes both sub_1.xsl and sub_2.xsl, processing of the <a> and <b> elements follows the default rules for resolving conflicts. The XSLT standard says that conflicting template rules are an error, which may be treated as such by the XSLT processor; alternatively, the standard allows the processor to accept the last such template rule in the style sheet, ignoring the others. Microsoft's XSLT processor (like most) follows this alternative processing route. Therefore:

  • The template rule for <b> which appears in sub_2.xsl will override that in sub_1.xsl, because sub_2.xsl's appears after sub_1.xsl's.
  • The template rule for <a> which appears in main.xsl itself will override that in sub_1.xsl, because main.xsl's appears after sub_1.xsl's.

Two rules determine the import precedence of a conflicting declaration:

  1. Any conflicting declaration in an imported style sheet has a lower import precedence than one in the importing style sheet.
  2. If one style sheet imports several others, then the first imported style sheet's declarations have lower precedence than the second's; the second's, higher than the third's; and so on.
Note The second rule is simply an explicit statement of the default "last one wins the tie" rule provided by XSLT's alternative conflict-resolution processing.

Using these rules, if the connections among the three style sheets are all <xsl:import> elements:

  • The template rule for <b> which appears in sub_1.xsl will override that in sub_2.xsl, because sub_1.xsl imports sub_2.xsl and therefore the declarations in sub_1 have a higher import precedence. This is the opposite of what happens if using <xsl:include> in the same case.
  • The template rule for <a> which appears in main.xsl itself will override that in sub_1.xsl, because main.xsl imports sub_1.xsl. This result is identical to the result when using <xsl:include>—but for a different, explicit reason.


Avoiding Conflicting Rules by Using <xsl:apply-imports>

Using imported (vs. included) style sheets has one other advantage: An included style sheet's declarations will simply be either applied or not, depending on the presence of conflicting declarations in the including style sheet and the sequence in which the conflicting declarations appear.

When you import a style sheet, however, you have another option: to supplement the imported declarations with others. To do so, the importing style sheet needs an appropriate <xsl:import> element as always; however, an <xsl:apply-imports> element also appears at the appropriate point in the template rule which would otherwise simply override its counterpart in the imported style sheet.

The syntax of the empty <xsl:apply-imports> element is straightforward, not even including any attributes:

<xsl:apply-imports/>

To see how this can be used, consider the files discussed earlier in this topic:

  • jamming.xml (in Initial Example for Importing Style Sheets)
  • jamming.xsl (in Using <xsl:include> to Insert an XSLT File)
  • chord.xsl (in Using <xsl:include> to Insert an XSLT File)

The above version of jamming.xsl contains template rules for processing fiction-related elements in the Synchronized Jamming book, and includes two style sheets (via <xsl:include>) which handle other elements, such as markup code and musical annotations.

We're going to start off by changing the line in jamming.xsl which reads:

<xsl:include href="chord.xsl"/>

to:

<xsl:import href="chord.xsl"/>
Note Because any <xsl:import> elements must be the first top-level elements in a style sheet, we also have to move it to a position above the <xsl:include href="markup_code.xsl"/> element in jamming.xsl.

So far, this has no effect on the output as viewed in Internet Explorer. Since jamming.xsl itself has no template rules for processing jamming.xml's <chord> element (and its attributes and child elements), no conflict is introduced.

The problem which Synchronized Jamming's production designers now face is a conflict not among template rules, but among design standards: their own design standards assert that any tables embedded in Web pages be surrounded by a double box, to make them stand out from plain text. They've got three choices for resolving the design conflict:

  1. Do nothing further, simply accepting ScootMusic's styling of the <chord> element as a borderless table (and thereby discard, for this book only, their own design standards for tables).
  2. Physically copy and paste the contents of chord.xsl's template rule into jamming.xsl. The drawback here is that if ScootMusic ever changes chord.xsl, for consistency's sake Synchronized Jamming's designers will have to re-edit jamming.xsl.
  3. Use an <xsl:apply-imports> to customize the table's appearance, both incorporating chord.xsl's template rule for the <chord> branch of the source tree and double-bordering it as well.

To accomplish option #3, add a template rule for the <chord> element to jamming.xsl, as follows:

<xsl:template match="chord">
   <div style="border-style:double; width:50%">
      <xsl:apply-imports/>
   </div>
</xsl:template>

The XSLT processor creates the bordered <div> element in the result tree at the point of the source tree's <chord> element. Then, at the point of the <xsl:apply-imports>, it examines all imported style sheets to see if they, too, provide a template rule for the <chord> element. If so, that template rule is fired within the resulting <div> element. The effect is as though the <chord> element's only template rule looked like this (portion from chord.xsl highlighted):

<xsl:template match="chord">
   <div style="border-style:double; width:50%">
   <div style="width:75%; margin-left:20; padding:10">
         <table border="0">
         [and so on]
      </table>
   </div>
</div>
</xsl:template>

Formatted Output

When viewed in Internet Explorer, the relevant portion of the page now appears as follows:


Finished Example for Importing and Including

Example

XML File (jamming.xml)

Here's a brief excerpt from Synchronized Jamming's first chapter. The book's structure is a mix of common elements of fiction, literal HTML code, and musical annotation.

<?xml version="1.0"?>
<?xml:stylesheet type="text/xsl" href="jamming.xsl"?>
<novel copyright="2001" isbn="555000000X">
   <title>Synchronized Jamming</title>
   <author>Kari Hensien</author>
   <chapter number="1">
      <title>The Bleeding Edge</title>
      <epigraph><text>Any sufficiently advanced technology is indistinguishable from noise.</text><author>Canopy Rose</author><source>The Fusion Manifesto</source></epigraph>
      <para>Politics. Technology. Rock'n'roll. All you needed to know about the underground band known as Canopy Rose was right there in the first couple grafs of their so-called "Fusion Manifesto":</para>
      <markup_code><![CDATA[
<html>
<head><title>Fused</title></head>
<body>
<p>Listen. You know as well as we do...</p>
<p>... the sound of one hand jammin':</p>
]]></markup_code>
      <chord duration="4.5" units="seconds" voice="steel" vibrato="on">
         <note>A</note>
         <note>C</note>
      </chord>
      <markup_code><![CDATA[
<p>Welcome to the block party. Welcome to the revolution.</p>
</body>
</html>
]]></markup_code>
   </chapter>
</novel>

XSLT File (jamming.xsl)

This is the final version of the file.

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/TR/REC-html40">

<xsl:import href="chord.xsl"/>
<xsl:include href="markup_code.xsl"/>

<xsl:template match="novel">
   <html>
      <head>
         <title>Excerpt:
            "<xsl:value-of select="title"/>,"
            by
            <xsl:value-of select="author"/>
         </title>
         <style>
            * {font-family: Arial,Helvetica,Univers,sans-serif}
            pre {font-family: Courier New,Courier,monospace}
         </style>
      </head>
      <body>
         <h2>Excerpt:<br/>
         <em><xsl:value-of select="title"/></em></h2>
         <h3>by <xsl:value-of select="author"/></h3>
         <h6>Copyright <xsl:value-of select="@copyright"/>
            by <xsl:value-of select="author"/></h6>
         <h6>Scootney Publishing / ISBN
            <xsl:value-of select="@isbn"/></h6>
         <hr size="2" width="75%" align="left"/>
         <xsl:apply-templates />
      </body>
   </html>
</xsl:template>

<xsl:template match="novel/title">
</xsl:template>

<xsl:template match="novel/author">
</xsl:template>

<xsl:template match="chapter">
   <div style="width:75%">
      <h2>Chapter <xsl:value-of select="@number"/>:<br/>
         <xsl:value-of select="title"/></h2>
      <xsl:apply-templates/>
   </div>
</xsl:template>

<xsl:template match="chapter/title">
</xsl:template>

<xsl:template match="epigraph">
   <div style="width:50%; float:right; margin:5; padding:5; background-color:silver; border-style:double; border-left-width:0; border-right-width:0">
      <xsl:apply-templates/>
   </div>
</xsl:template>

<xsl:template match="epigraph/text">
   <div>
      <em><value-of select="."/></em>
      <xsl:apply-templates/>
   </div>
</xsl:template>

<xsl:template match="epigraph/author">
   -- <xsl-value-of select="."/>
   <xsl:apply-templates/>
</xsl:template>

<xsl:template match="epigraph/source">
   (<em><xsl:value-of select="."/></em>)
</xsl:template>

<xsl:template match="para">
   <p><xsl:apply-imports/></p>
</xsl:template>

<xsl:template match="chord">
   <div style="border-style:double; width:50%">
      <xsl:apply-imports/>
   </div>
</xsl:template>

</xsl:stylesheet>

Imported XSLT File (chord.xsl)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/TR/REC-html40">

<xsl:template match="chord">
   <div style="width:75%; margin-left:20; padding:10">
      <table border="0">
         <tr>
            <th style="background-color: yellow">
               <xsl:attribute name="colspan"><xsl:value-of select="count(note)"/></xsl:attribute>
               Chord Notes
            </th>
         </tr>
         <tr>
            <xsl:for-each select="note">
               <td><b><xsl:value-of select="."/></b></td>
            </xsl:for-each>
         </tr>
         <tr>
            <td style="background-color: yellow">
               <xsl:attribute name="colspan"><xsl:value-of select="count(note)"/></xsl:attribute>
               Duration:
                  <xsl:value-of select="@duration"/><xsl:text> </xsl:text>
                  <xsl:value-of select="@units"/>
            </td>
         </tr>
         <tr>
            <td style="background-color: yellow">
               <xsl:attribute name="colspan"><xsl:value-of select="count(note)"/></xsl:attribute>
               Voice: <xsl:value-of select="@voice"/>
            </td>
         </tr>
         <tr>
            <td style="background-color: yellow">
               <xsl:attribute name="colspan"><xsl:value-of select="count(note)"/></xsl:attribute>
               Vibrato: <xsl:value-of select="@vibrato"/>
            </td>
         </tr>
      </table>
   </div>
</xsl:template>

</xsl:stylesheet>

Included XSLT File (markup_code.xsl)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/TR/REC-html40">

<xsl:template match="markup_code">
   <div style="width:75%; margin-left:20; padding:10">
      <pre><xsl:value-of select="."/></pre>
   </div>
</xsl:template>

</xsl:stylesheet>

Formatted Output


Using XSLT Keys to Increase Performance

Using XSLT to process a large XML document with many data points may pose performance questions, especially when specific nodes within the document are to be processed repeatedly within a single transformation.

For example, a document representing a publishing company's book catalog may contain data on hundreds or thousands of books. In a given transformation, many of these book titles may be referenced a dozen times, not just in the individual books' descriptions but also in an index of all titles, a list of featured titles, and so on. Searching or cross-referencing the document many times, from start to finish, for a given title or a title that matches a specific condition can result in unacceptable performance.

XSLT solves this problem by supporting the use of keys to uniquely identify a node or class of nodes. Each key is used by the XSLT processor, such as the MSXML processor built into Microsoft Internet Explorer, to build an index which the processor can reference when a particular value is needed; this index enables the processor to retrieve the keyed node without searching for it. Using keys can also greatly simplify coding of XPath expressions.

  • Deciding whether to Use IDs or Keys
  • Using the <xsl:key> Element
  • Using the key() Function
  • Using XSLT Keys to Group Data

This section uses the following sample files:

  • Sample XML Data File for XSLT Keys (booksvariant.xml)
  • Sample XSLT File for XSLT Keys (lib_cat.xsl)


Deciding whether to Use IDs or Keys

The XML specification itself provides a simple means to uniquely identify an element, using an ID-type attribute. A conforming XML processor, such as the MSXML processor, is expected to build an index of any elements with IDs, enabling them to be cross-referenced, for example, by other elements with a corresponding IDREF-type attribute.

Why, then, does the XSLT standard provide keys for essentially the same purpose? There are several drawbacks to using IDs alone:

  • You must use an attribute value as the element's ID; you can't use the element's content, or the content of some other element with a particular relationship (such as child or preceding-sibling) to the element you want to identify. If an author's name is a desired index value, but is held in an <author_name> element rather than an attribute, then there's no way using XML alone to index on the name.
  • A given element can have no more than one ID-type attribute. This means, for example, that both a book's ISBN and its publication date cannot be held in ID-type attributes.
  • Each ID value must be unique in a given document. If pub_date is an ID-type attribute, this effectively prevents two books from sharing the same publication date.
  • In order to use ID attributes at all, they must be declared as such in a Document Type Definition (DTD). If the document is merely well-formed and therefore does not use a DTD, then none of its attributes can be IDs.
  • All IDs in a document constitute basically a single set of IDs. You can't establish multiple, somehow different but related sets of IDs. For instance, if you've designed a document type which uses ISBNs to uniquely identify books, and "author numbers" to uniquely identify authors, there's no way to treat these two "kinds of IDs" distinctly.
  • The name of an XML ID must be a legitimate XML name. For example, it cannot contain spaces, and it must start with a letter. This forces you to use somewhat artificial values such as "isbn0123456789" and "AFarewellToArms" as the unique identifier, rather than the more natural "0123456789" and "A Farewell to Arms," respectively.

The use of keys enables an XSLT style sheet to circumvent any or all of these restrictions.


Using the <xsl:key> Element

The <xsl:key> element is a top-level element—that is, a child of the <xsl:stylesheet> element—whose purpose is to declare the name of a key. The node corresponding to the key can then be retrieved using the key() function (see Using the key() Function). You can include as many <xsl:key> elements in your style sheets as needed.

The syntax for the <xsl:key> element is:

<xsl:key name="name" match="node" use="expression" />

Note that <xsl:key> is always an empty element.

All three attributes are required. Their values are as follows:

  • name: This is a text string which assigns a name to the key. This name will be used by the key() function to retrieve the corresponding node from the source tree.
  • node: This is the name of the node to which to assign the key. It may not contain a reference to a variable name.
  • expression: Here, use an XPath expression which will be value of the key. Note that this can be a string instead of one of the more common XPath expressions consisting of one or more location steps. It can also be a call to the XSLT generate-id Function, which will have the effect of assigning a unique value to the key for this node even if no other unique value is available. The expression, like the node, may not contain a reference to a variable name.

There are no constraints on the number of keys which may be assigned to a given node; likewise, any number of nodes may be assigned keys with the same name and/or value.

Note Although the standard itself sets few limits on the use of keys, a given XSLT application using keys may be limited by the hardware environment (particularly memory) in which the application is running. Also, the performance gains made possible by the use of keys require a trade-off: the time and memory resources required up-front to build the index of keys when the style sheet is first processed, before the first transformation occurs. While it may be tempting to index every possible node in a large document in dozens of ways, always bear these two practical considerations in mind when using keys.

An example of the <xsl:key> element is:

<xsl:key name="isbn_key" match="book" use="@isbn" />

This declares a key named isbn_key, which will be assigned to each <book> element and will have as its value the value of that <book> element's isbn attribute. Thus, the book Jambing on the Trixels will be assigned an isbn_key whose value is "991100-001"; For Love of a Toothpick, "991100-002"; and so on.

Here is another example:

<xsl:key name="categ_key" match="book" use="category" />

This tells the XSLT processor to build, for each <book> element, a key for its <category> child.

While a key is most commonly assigned to an element based on the value of a child text node or element, or the value of an attribute, the use attribute can readily take any other XPath expression relative to the element. For instance, you could assign a key as follows:

<xsl:key name="book_for_categ" match="category"
use="../title" />

This assigns to each <category> element a key whose value is the corresponding <book> element's <title> child.

Files Used for This Topic

  • Sample XML Data File for XSLT Keys
  • Sample XSLT File for XSLT Keys


Using the key() Function

The other side of the <xsl:key> element is provided by the built-in XSLT key() function. Its purpose is to retrieve the node or nodes keyed to a particular name and value.

The syntax of the key() function is:

key(name, value)

The result of the key() function is a node-set containing all nodes which match the key identified by the arguments. Arguments passed to it are:

  • name: a string giving the name of the key to use. It corresponds to the name of one or more keys defined by <xsl:key> elements.
  • value: the value of the desired key. Technically, this argument can be of any data type; however, if it is a node-set, the function will return all nodes with the same value. Note that this argument can be a variable reference.

If the value of name does not match the name of a key defined by a corresponding <xsl:key> element then the result of using the key() function will be an empty node-set.

The following table shows some brief examples of the node-sets returned by calls to the key() function:

Key declaration key() function call Returns
<xsl:key name="isbn_key" match="book" use="@isbn"/>

key("isbn_key", "991100-102")
 The <book> element corresponding to the title Quantum Superstring Electrodynamics for Newbies
<xsl:key name="categ_key" match="book" use="category"/>

key("categ_key", "Fiction")
 The <book> element corresponding to Jambing on the Trixels
<xsl:key name="categ_key" match="book" use="category"/>

key("categ_key", "Non-fiction")
 Every <book> element except the one corresponding to Jambing on the Trixels
<xsl:key name="author_id" match="book" use="author"/>

key("author_id", contains("Culbert"))
 The two <book> elements corresponding to Fretting Over Your Guitar and Quantum Superstring Electrodynamics for Newbies

Files Used for This Topic

  • Sample XML Data File for XSLT Keys (booksvariant.xml)
  • Sample XSLT File for XSLT Keys (lib_cat.xsl)


Sample XML Data File for XSLT Keys

Topics in this section use the following XML document, which is a portion of the catalog at a large metropolitan public library, developed by Scootney Publishing as part of a promotional exhibit.

XML File (booksvariant.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="lib_cat.xsl"?>
<!DOCTYPE book [
<!ENTITY oumlaut "&#38;#246;">
]>
<lib_cat>
   <book isbn="991100-001" catnum="101.3490">
      <title>Jambing on the Trixels</title>
      <author>Tristan Randall</author>
      <publisher>Scootney Publishing</publisher>
      <copyright>2000</copyright>
      <pages>496</pages>
      <category>Fiction</category>
      <description>Tristan Randall scores another action-adventure hit with
      this fast-paced tale of murder among the faculty teaching semantics at
      a small New England university.</description>
   </book>
   <book isbn="991100-002" catnum="432.9431">
      <title>For Love of a Toothpick</title>
      <author>J&oumlaut;rg Frey</author>
      <publisher>Scootney Publishing</publisher>
      <copyright>2000</copyright>
      <pages>175</pages>
      <category>Non-fiction</category>
      <description>Looking for a whimsical introduction to the
      mysterious world of miscellaneous dining and personal-grooming
      utensils? This is the book for you!</description>
   </book>
   <book isbn="991100-010" catnum="894.3207">
      <title>Desperation 101</title>
      <author>Jack Gode</author>
      <publisher>Scootney Publishing</publisher>
      <copyright>2000</copyright>
      <pages>262</pages>
      <category>Non-fiction</category>
      <description>Self-help guru Gode recounts his personal journey
      from confusion to certainty, with the help of a most unusual
      therapy: highway hypnosis.</description>
   </book>
   <book isbn="991100-008" catnum="562.1093">
      <title>Fretting Over Your Guitar</title>
      <author>Becki Culbert</author>
      <publisher>ScootMusic (a Division of Scootney Publishing)</publisher>
      <copyright>1998</copyright>
      <pages>160</pages>
      <category>Non-fiction</category>
      <description>In part a traditional "fake book," in part a profound
      exploration of the relationship between musician and instrument,
this little volume surprises the reader on every page.</description>
   </book>
   <book isbn="991100-102" catnum="450.9043">
      <title>Quantum Superstring Electrodynamics for Newbies</title>
      <author>Becki Culbert</author>
      <publisher>Scootney Publishing</publisher>
      <copyright>2001</copyright>
      <pages>656</pages>
      <category>Non-fiction</category>
      <description>Multi-dimensional author Culbert turns her attention to
      Quantum Superstring Electrodynamics, clearly explaining every facet
      of this frighteningly complex topic in a mere 600-plus pages, many
      of them containing words understandable to the rankest of
      newcomers.</description>
   </book>
</lib_cat>


Sample XSLT File for XSLT Keys

Some topics in this section use the following file.

XSLT File (lib_cat.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:key name="categ_key" match="book" use="category"/>
<xsl:key name="author_key" match="book" use="author"/>

<xsl:template match="/">
    <html>
        <head>
            <title>Scootney Publishing: Special Exhibit</title>
            <style>
                h1 {font-family: Arial,Helvetica,Univers,sans-serif;
                    font-size: 18pt; font-weight: bold;
                    background-color: teal;
                    width: 75%}
                h2 {font-family: Arial,Helvetica,Univers,sans-serif;
                    font-size: 14pt; font-weight: bold;
                    background-color: white;
                    width: 75%}
                h3 {font-family: Arial,Helvetica,Univers,sans-serif;
                    font-size: 12pt; font-weight: bold;
                    background-color: gold;
                    width: 75%;
                    border-width: 1;
                    border-style: solid}
            </style>
        </head>
        <body>
            <h1>Scootney Publishing: Special Exhibit Catalog</h1>
            <xsl:apply-templates select="lib_cat" mode="grp_categ"/>
            <xsl:apply-templates select="lib_cat" mode="grp_author"/>
        </body>
    </html>
</xsl:template>

<xsl:template match="lib_cat" mode="grp_categ">
    <h2>Titles Grouped by Category</h2>
    <xsl:for-each select="book[count(. | key('categ_key', category)[1])=1]">
        <h3><xsl:value-of select="category" /></h3>
        <xsl:for-each select="key('categ_key', category)">
            <xsl:sort select="title"/>
            <table border="0" width="75%">
                <tr>
                    <th width="10%" align="right">Title</th>
                    <td width="90%" align="left"><xsl:value-of select="title" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right">Author</th>
                    <td width="90%" align="left"><xsl:value-of select="author" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right">Copyright</th>
                    <td width="90%" align="left"><xsl:value-of select="copyright" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right">Pages</th>
                    <td width="90%" align="left"><xsl:value-of select="pages" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right" valign="top">Summary</th>
                    <td width="90%" align="left" valign="top"><xsl:value-of select="description" /></td>
                </tr>
            </table>
            <hr width="75%" align="left"/>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

<xsl:template match="lib_cat" mode="grp_author">
    <h2>Titles Grouped by Author</h2>
    <xsl:for-each select="book[generate-id() = generate-id(key('author_key', author)[1])]">
        <xsl:sort select="author"/>
        <h3><xsl:value-of select="author" /></h3>
        <xsl:for-each select="key('author_key', author)">
            <xsl:sort select="title"/>
            <table border="0" width="75%">
                <tr>
                    <th width="10%" align="right">Title</th>
                    <td width="90%" align="left"><xsl:value-of select="title" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right">Category</th>
                    <td width="90%" align="left"><xsl:value-of select="category" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right">Copyright</th>
                    <td width="90%" align="left"><xsl:value-of select="copyright" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right">Pages</th>
                    <td width="90%" align="left"><xsl:value-of select="pages" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right" valign="top">Summary</th>
                    <td width="90%" align="left" valign="top"><xsl:value-of select="description" /></td>
                </tr>
            </table>
            <hr width="75%" align="left"/>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>


Using XSLT Keys to Group Data

One of the most common uses of keys is in grouping data in a document. Sorting is easy enough, using the <xsl:sort> element; but with sorting alone, you're forced to repeat each of the items establishing a "category." What if you want to display the "category" only once, followed by a list of all items which fall under it?

The public library participating in Scootney's promotional exhibit wants to produce a single Web page showing the titles in the exhibit grouped in two ways: one showing the titles grouped by category, and one showing them grouped by author.

The style sheet (lib_cat2.xsl) developed by the library defines two keys corresponding to these two groupings:

<xsl:key name="categ_key" match="book" use="genre"/>
<xsl:key name="author_key" match="book" use="author"/>

There are also two template rules for the root <catalog> element, using modes to enable the element to be processed twice—once for each grouping. These template rules are invoked by <xsl:apply-templates> elements within the template rule for the document root:

<xsl:template match="/">
...
         <xsl:apply-templates select="catalog" mode="grp_categ"/>
         <xsl:apply-templates select="catalog" mode="grp_author"/>
...
</xsl:template>

The two template rules for the <catalog> element take two slightly different approaches to the problem of grouping, although both use keys to do so; we'll look at each separately.

  • Grouping Data by Examining the Keyed Node-set
  • Grouping Data by Using generate-id()

Files Used for This Topic

  • Sample XML Data File for XSLT Keys (booksvariant.xml)
  • Sample XSLT File for XSLT Keys (lib_cat.xsl)

See Also

Dividing Sort Items into Pages by Using Variables


Grouping Data by Examining the Keyed Node-set

By definition, a node-set cannot contain a given node more than once. Look at the following portion of the <catalog> element's template rule (grp_categ mode, for grouping the books by genre) and see if you can tell what the references to the categ_key key are doing:

<xsl:template match="catalog" mode="grp_categ">
    <h2>Titles Grouped by Genre</h2>
    <xsl:for-each select="book[count(. | key('categ_key', genre)[1])=1]">
        <h3><xsl:value-of select="genre" /></h3>
        <xsl:for-each select="key('categ_key', genre)">
            <xsl:sort select="title"/>
...
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

The predicate portion of the outer <xsl:for-each> element's select attribute looks rather complex, but essentially consists of two separate conditions joined by the XPath "or" operator (a pipe or vertical-bar symbol, |). In particular, it says to process each <book> element if it represents:

  • the only book (count(.)=1); or
  • the first book for a category (count(key('categ_key', genre)[1]).

When either of these conditions is met, the template rule instantiates a level-3 heading in the result tree, displaying the name of the book's category.

The second reference to the key() function is where the actual grouping occurs, within the category established by the outer <xsl:for-each>. It says, within each of the node-sets established by the categ_key key, to list the titles and so on of all books in the group.

Example

XML File (books.xml)

Use the Sample XML File (books.xml). Below the line <?xml version='1.0'?>, add the following line:

<?xml-stylesheet type="text/xsl" href="lib_cat2.xsl"?>

XSLT File (lib_cat2.xsl)

This file uses the <genre> element as the category for sorting.

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:key name="categ_key" match="book" use="genre"/>
<xsl:key name="author_key" match="book" use="author"/>

<xsl:template match="/">
    <html>
        <head>
            <title>Scootney Publishing: Special Exhibit</title>
            <style>
                h1 {font-family: Arial,Helvetica,Univers,sans-serif;
                    font-size: 18pt; font-weight: bold;
                    background-color: teal;
                    width: 75%}
                h2 {font-family: Arial,Helvetica,Univers,sans-serif;
                    font-size: 14pt; font-weight: bold;
                    background-color: white;
                    width: 75%}
                h3 {font-family: Arial,Helvetica,Univers,sans-serif;
                    font-size: 12pt; font-weight: bold;
                    background-color: gold;
                    width: 75%;
                    border-width: 1;
                    border-style: solid}
            </style>
        </head>
        <body>
            <h1>Scootney Publishing: Special Exhibit Catalog</h1>
            <xsl:apply-templates select="catalog" mode="grp_categ"/>
            <xsl:apply-templates select="catalog" mode="grp_author"/>
        </body>
    </html>
</xsl:template>

<xsl:template match="catalog" mode="grp_categ">
    <h2>Titles Grouped by Genre</h2>
    <xsl:for-each select="book[count(. | key('categ_key', genre)[1])=1]">
        <h3><xsl:value-of select="genre" /></h3>
        <xsl:for-each select="key('categ_key', genre)">
            <xsl:sort select="title"/>
            <table border="0" width="75%">
                <tr>
                    <th width="10%" align="right">Title</th>
                    <td width="90%" align="left"><xsl:value-of select="title" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right">Author</th>
                    <td width="90%" align="left"><xsl:value-of select="author" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right">Copyright</th>
                    <td width="90%" align="left"><xsl:value-of select="publish_date" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right">Price</th>
                    <td width="90%" align="left"><xsl:value-of select="price" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right" valign="top">Summary</th>
                    <td width="90%" align="left" valign="top"><xsl:value-of select="description" /></td>
                </tr>
            </table>
            <hr width="75%" align="left"/>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

<xsl:template match="catalog" mode="grp_author">
    <h2>Titles Grouped by Author</h2>
    <xsl:for-each select="book[generate-id() = generate-id(key('author_key', author)[1])]">
        <xsl:sort select="author"/>
        <h3><xsl:value-of select="author" /></h3>
        <xsl:for-each select="key('author_key', author)">
            <xsl:sort select="title"/>
            <table border="0" width="75%">
                <tr>
                    <th width="10%" align="right">Title</th>
                    <td width="90%" align="left"><xsl:value-of select="title" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right">Genre</th>
                    <td width="90%" align="left"><xsl:value-of select="genre" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right">Copyright</th>
                    <td width="90%" align="left"><xsl:value-of select="publish_date" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right">Price</th>
                    <td width="90%" align="left"><xsl:value-of select="price" /></td>
                </tr>
                <tr>
                    <th width="10%" align="right" valign="top">Summary</th>
                    <td width="90%" align="left" valign="top"><xsl:value-of select="description" /></td>
                </tr>
            </table>
            <hr width="75%" align="left"/>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Formatted Output

A portion of the output is shown here.


Grouping Data by Using generate-id()

As an alternative to the complex syntax necessary to examine each node in a key's node-set, you can take advantage of the generate-id() function's ability to uniquely identify a node.

Here's an excerpt from the template rule in lib_cat2.xsl (in Grouping Data by Examining the Keyed Node-set) which groups books by author's name:

<xsl:template match="catalog" mode="grp_author">
    <h2>Titles Grouped by Author</h2>
    <xsl:for-each select="book[generate-id() = generate-id(key('author_key', author)[1])]">
        <xsl:sort select="author"/>
        <h3><xsl:value-of select="author" /></h3>
        <xsl:for-each select="key('author_key', author)">
            <xsl:sort select="title"/>
...
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

Here, the predicate portion of the outer <xsl:for-each> element's select attribute says: "Select a <book> element only if its generated ID equals that of the first <book> element in the node-set established by the author_key key." When such a <book> is found, the template rule instantiates a level-3 heading displaying the corresponding <author> element's value.

The inner <xsl:for-each> says to select all <book> elements in the node-set established by the author_key key, sorts the books by a given author by their titles, and so on.

Example

XML File (books.xml)

Use the Sample XML File (books.xml). Below the line <?xml version='1.0'?>, add the following line:

<?xml-stylesheet type="text/xsl" href="lib_cat2.xsl"?>

XSLT File (lib_cat2.xsl)

See the listing in Grouping Data by Examining the Keyed Node-set.

Formatted Output

A portion of the output is shown here.

See Also

Grouping Data by Examining the Keyed Node-set | generate-id Function


Forwards-Compatible Processing to Support Future Versions

XSLT supports future versions of XSLT by providing a graceful fallback if a given parser doesn't implement some feature in the newer version. This is Forwards-Compatible Processing.

An XSLT 1.0 compatible stylesheet includes in the <xsl:stylesheet> element an attribute called version set to the value 1.0. If an unrecognized element or attribute in the xsl: namespace (say xsl:while) is used in the stylesheet, then the parser will return an error (if viewing an XSLT transformation in the IE5+ browser, this will be the familiar message in the browser window that XSLT reports when it can't process an element or attribute).

If, however, an XSLT stylesheet with a higher version number is passed into the 1.0 processor, the parser won't know whether an unknown xsl element or attribute is passed as an error or is part of the newer version's set of commands. As such, the parser is instructed to ignore the element or attribute and anything within it. This guarantees that the XSLT stylesheet won't break if the parser has to handle newer versions of code.

For example, the following version 1.1 stylesheet includes a new XSLT 1.1 feature called the xsl:exciting-new-1.1-feature element, which is not contained in XSLT version 1.0:

XSLT File (forward_compat1.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.1"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <xsl:choose>

      <xsl:when test="system-property('xsl:version') >= 1.1">
         <xsl:exciting-new-1.1-feature/>
      </xsl:when>

      <xsl:otherwise>
         <html>
         <head>
            <title>XSLT 1.1 required</title>
         </head>
         <body>
            <p>Sorry, this stylesheet requires XSLT 1.1.</p>
         </body>
         </html>
      </xsl:otherwise>

   </xsl:choose>
</xsl:template>

</xsl:stylesheet>

The elements are parsed and validated prior to being executed (think of it as design-time versus run-time code) and forward-compatible processing insures that the <xsl:exciting-new-1.1-feature/> will not automatically generate an error in the parsing phase. XSLT also supplies a number of functions, such as system-property(), function-available(), and element-available() that can be used to determine at run time whether such a function or element exists or which version is currently in use.

Forward-compatible processing can also work with the <xsl:fallback> element. This element provides an alternative course of action for an element if it doesn't exist in the version.

XSLT File (forward_compat2.xsl)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="forward_compat2.xsl"?>
<xsl:stylesheet version="1.1"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <table>
   <xsl:for var="i" start="0" test="$i &lt; 10" increment="1">
      <tr>
         <td><xsl:value-of select="$i"/></td>
         <td><xsl:value-of select="$i * $i"/></td>
      </tr>
      <xsl:fallback>
         <xsl:message terminate="yes">The command xsl:for is not supported.</xsl:message>
      </xsl:fallback>
   </xsl:for>
   </table>
</xsl:template>

</xsl:stylesheet>

In this particular case, the fallback terminates the processing with an error message that will be displayed in the browser. A given term can have more than one fallback element – they will all be evaluated in sequential order. Finally, if no fallback is provided, then the element is simply ignored.

Forward-compatible processing is also used in cases where extensions have been applied to the XSLT parser. The extension namespace must be specified in the <xsl:stylesheet> element using the extension-element-prefixes (or xsl:extension-element-prefixes)with each extension prefix used by the parser separated by white space.

See Also

Supported XSLT Features


Creating Interactive XSLT

This section covers the following:

  • Using ASP with XSLT Processor and Template Objects
  • Debugging XSLT
  • Using XML Data Islands and Client-Side XSLT
  • Controlling Output Format with the media-type Attribute
  • Extending XSLT


Using ASP with XSLT Processor and Template Objects

XSLT is about much more than simply creating HTML output. It is a language for handling complex transformations, and as such can form the foundation of sophisticated web applications. However, XSLT cannot exist by itself – it has to be "hosted" by some other programming language, by way of the DOM. Finding the right balance between working with the DOM and working with XSLT is largely a matter of experience, though in general, the more the work involves converting one XML structure to another via XSLT the less the DOM should be invoked.

Microsoft Active Server Pages currently process the bulk of all XSLT work on the Internet. As a way of being able to host the necessary DOM, ASP pages can produce very simple XSLT, or can be designed to optimize the XSLT output for high performance pages. The key to developing XSLT applications that scale well is to utilize the XSLT Template and Processor object.

One of the most powerful innovations that emerged from the revisions to the MSXML parser was the development of the XSLT Processor. This COM component handles one of the major problems with working with XSLT: the time and resources it takes to compile the initial XSLT style sheet. Using the transformNode() command that was part of the older MSXML2.5 parser, the style-sheet was first converted into a tokenized transformation, essentially a temporary binary representation of the transformation for easier processing, then the XML document to be transformed was applied to the internal transformation and the output converted into a string. The transformNodeToObject() kept the resulting transformation as a DOM object, but still had the overhead of compiling the stylesheet each and every time a transformation was applied.

Because this compilation stage proved to be a significant overhead for XSLT transformations, many developers were reluctant to use XSLT for generation on high demand servers. To get around this problem in the next release, Microsoft introduced the XSLTemplate object and its child IXSLProcessor. The Template object takes a stylesheet (as a DOM object) and creates an XSL Processor from that object. Once created, the processor can be cached so that the object doesn't need to be recompiled, significantly cutting down on the processing overhead.

Additionally, it is possible to assign to the XSLT Processor object thus created both parameters and COM objects via namespaces, and to change both the input and output of the XSLT Processor so that it can be used with any producer or consumer of XML. Because of this, you can pass XML to the server from the browser (through something like the XMLHTTP component, discussed in section 2.6.3), transform it, and send it back through the ASP Response object, or save it to a local file or to some other XML consumer.

Advantages of the XSL Processor Object over TransformNode()

The XSLT Processor can seem to be fairly verbose compared to the use of the TransformNode() function that's a part of the MSXML3 DOM model, and you may be wondering whether the amount of code involved is worth the benefit. As it stands, the Processor definitely is worth the effort, for a number of reasons:

  • Scalability. Both the XSL Template and the XSL Processor can be cached as server variables. While in general it is not a good idea to cache an XML document because of the memory constraints involved, compiled XSLT transformations are functionally more similar to COM objects than they are to large XML data structures.
  • Performance. A compiled XSLT object (which is what an XSL Processor basically is) does not have to rebuild the transformation every time it is invoked, reducing the processing load on it by a considerable amount. The XSL Template can also be cached as an MTS object, which in turn means that the processing of this object can be optimized not just within a session but across sessions.
  • Parameterization. The XSLT Processor makes passing parameter information into the style sheet much easier, and because the compiled XSLT objects have hooks in place for parameterization, you don't lost the benefits of working with the objects as components.
  • Extensions. You can also pass COM objects into XSLT documents as namespace extensions. For more information, see Extending XSLT.

Example

This example shows what can be done with the new XSLT Processor. For a catalog of books, you can display only the books of a specific genre. The style sheet includes parameters that can be altered by a selection box. The stylesheet includes both the selection box and a table that displays the requested subset of books (or that displays all of them if no specific option is given).

The example uses these files:

  • Sample XSLT File for ASP XSLT Processor Objects (catalogFilter.xsl)
  • Sample ASP Script for XSLT Processor Objects (catalog.asp)
  • Sample XML File (books.xml)

The ASP script contains the following functions:

  • The loadSource() function creates a free threaded DOM document that holds the catalog XML structure. The free-threaded nature of the document is important, as this generates a document that processes on a thread separate from the ASP document itself, something that is critical for scalability if either the source or transformation XML is cached.
  • The getProcessor() function similarly loads in the XSL document, but it differs from loadSource() in that an XSL Template object is instantiated within the function and the XSL document is assigned as the stylesheet for the appropriate template. Once this assignment is made (and only once its made) the createProcessor() method is invoked on the XSL Template object to return an XSL Processor object that gets passed back to the calling function.
  • The transformData() assigns the input for the processor to the source document and sets the output to the Response object – the resulting XML structure is converted into a string and sent to the client for this particular case. Finally this calls the transform() method on the processor object to actually perform the transformation that pumps the XML from the input device through the stylesheet and from there to the output device.
  • The main() function does the bulk of the parametric processing. It tests to see if a "genre" parameter was passed in either a form or a query string and assigns a default value of "all" to the parameter if nothing was passed. This value is then assigned as a parameter to the XSLT Processor object using processor.addParameter (note that the stylesheet must have this parameter defined beforehand, even if no value is associated with the parameter in the XSLT document).

To run this example

Put the files in a directory on an HTTP server. Enter a URL such as http://www.myserver.com/catalog.asp.

Results

When the ASP file is first invoked with no parameters (such as the URL format http://www.myserver.com/catalog.asp) it automatically defaults to showing all records, including a column that gives the current genre.

When the drop-down list box is set to a different field (such as "Computer") then the column for Genre is dropped and only those books in the indicated genre are shown, in alphabetical order:

It is worth noting in this example that the main() function can be modified to handle any data source, style sheet and set of parameters without changing any other routines here – regardless of what the style sheet is. This can even extend to making into HTML form parameters the names of the specific style sheet to be applied. This has application in such areas as working with different types of output (HTML 4.0, IE5 targeted HTML, XML, WML, and so on), handling SOAP objects, and changing the specific representation of information to differing needs (summaries, charts, graphs, and so on).


Sample XSLT File for ASP XSLT Processor Objects

XSLT File (CatalogFilter.xsl)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt"
        version="1.0">

        <xsl:output method="html"/>

        <xsl:param name="selected_genre" select="'all'"/>

        <xsl:template match="/">
            <html>
                <head>
                    <title>Displayed Catalog</title>
                </head>
                <body>
                    <style>
                        .catalog_genre_head {background-color:darkGreen;font-size:24pt;color:white;font-family:Impact;}
                        .catalog_head {background-color:green;font-size:18pt;color:white;font-family:Impact;}
                        .catalog_row0 {background-color:lightGreen;}
                        .catalog_row1 {background-color:white;}
                        .catalog_row_end {background-color:darkGreen;}
                    </style>
                    <form method="post" action="catalog.asp">
                    Genre
                    <select name="genre" value="{$selected_genre}" onchange="submit()">
                        <option value="all"><xsl:if test="$selected_genre='all'"><xsl:attribute name="selected">Selected</xsl:attribute></xsl:if>All</option>
                        <option value="Computer"><xsl:if test="$selected_genre='Computer'"><xsl:attribute name="selected">Selected</xsl:attribute></xsl:if>Computer</option>
                        <option value="Fantasy"><xsl:if test="$selected_genre='Fantasy'"><xsl:attribute name="selected">Selected</xsl:attribute></xsl:if>Fantasy</option>
                        <option value="Horror"><xsl:if test="$selected_genre='Horror'"><xsl:attribute name="selected">Selected</xsl:attribute></xsl:if>Horror</option>
                        <option value="Romance"><xsl:if test="$selected_genre='Romance'"><xsl:attribute name="selected">Selected</xsl:attribute></xsl:if>Romance</option>
                        <option value="Science Fiction"><xsl:if test="$selected_genre='Science Fiction'"><xsl:attribute name="selected">Selected</xsl:attribute></xsl:if>Science Fiction</option>
                    </select>
                    </form>
                    <br/>
                    <xsl:apply-templates select="catalog"/>
                </body>
            </html>
        </xsl:template>

        <xsl:template match="catalog">
            <table class="catalog_table">
                <xsl:apply-templates select="book[($selected_genre='all') or ($selected_genre=./genre)]">
                    <xsl:sort select="title"/>
                </xsl:apply-templates>
            </table>
        </xsl:template>

        <xsl:template match="book">
            <xsl:if test="position()=1">
            <tr class="catalog_genre_head"><td colspan="6">
            <xsl:choose>
            <xsl:when test="$selected_genre='all'">
            All Genres
            </xsl:when>
            <xsl:otherwise>
            Genre: <xsl:value-of select="genre"/>
            </xsl:otherwise>
            </xsl:choose>
            </td></tr>
            <tr class="catalog_head">
                <td>#</td>
                <td>Title</td>
                <td>Author</td>
                <td>Publication Date</td>
                <td>Description</td>
                <xsl:if test="$selected_genre='all'">
                <td>Genre</td>
                </xsl:if>
            </tr>
            </xsl:if>
            <tr class="catalog_row{position() mod 2}">
                <td><xsl:value-of select="position()"/></td>
                <td class="catalog_cell"><xsl:value-of select="title"/></td>
                <td class="catalog_cell"><xsl:value-of select="author"/></td>
                <td class="catalog_cell"><xsl:value-of select="publish_date"/></td>
                <td class="catalog_cell"><xsl:value-of select="description"/></td>
                <xsl:if test="$selected_genre='all'">
                <td class="catalog_cell"><xsl:value-of select="genre"/></td>
                </xsl:if>
            </tr>
            <xsl:if test="position()=last()">
            <tr class="catalog_row_end"><td colspan="6"> </td></tr>
            </xsl:if>
        </xsl:template>
    </xsl:stylesheet>


Sample ASP Script for XSLT Processor Objects

The following ASP script demonstrates most of the key features of the XSLT Processor and Template objects. It takes the "genre" parameter from a client-side HTML page and returns a table of all books from the book catalog in the given genre, sorted by Title.

ASP Script (catalog.asp)

<%@LANGUAGE="JavaScript"%>
<%Response.expires=-1;
// catalog.asp
// Sorts books from a given catalog by title, for a given Genre.
function loadSource(sourceName){
    var xmlDoc=new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
    xmlDoc.async=false;
    xmlDoc.load(Server.mapPath(sourceName));
    return xmlDoc;
    }

function getProcessor(transformName){
    if ("" + Session(transformName) == "undefined"){
        var xslDoc=new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
        var xslTemplate=new ActiveXObject("MSXML2.XSLTemplate");
        xslDoc.async=false;
        xslDoc.load(Server.mapPath(transformName));
        xslTemplate.stylesheet=xslDoc;
        xslProcessor=xslTemplate.createProcessor();
        Session(transformName)=xslProcessor;
        }
    else {
        xslProcessor=Session(transformName);
        }
    return xslProcessor;
    }

function transformData(srcDoc,processor){
    processor.input=srcDoc;
    processor.output=Response;
    processor.transform();
    return true;
    }

function main(){
    var srcDoc=loadSource("books.xml");
    var processor=getProcessor("catalogFilter.xsl");

    var genre=Request("genre");
    if(""+genre=="undefined"){
        genre="all";
        }
    else {
        genre=""+genre;
        }
    processor.addParameter("selected_genre",genre);
    transformData(srcDoc,processor);
    }

main();
 %>


Debugging XSLT

Debugging XSLT can be frustrating. There are currently few development environments that are specifically designed to work with XSLT, and separating errors within XSLT from errors that arise because of badly formed XML can frequently slow the development of style sheets. However, there are a few techniques that you can use to at least determine where XSLT errors occur and to make your code more robust from a debugging standpoint.

One of the simplest tools for debugging your XSLT code is to use the Internet Explorer 5.0 browser itself as a way of looking at the style sheet. By opening up the style sheet within IE5 or above, you can ascertain whether or not a given XML structures is well formed. Typically, the errors that you'll discover in this manner are strictly syntactical: a tag with no closing tag, improperly quoted attributes, the use of illegal characters within XML structures ,and so forth.

you can also use the Internet Explorer 5 browser to apply a preliminary style sheet to what a known XML structure. In this case, you simply create a processing instruction at the beginning of your XML document that tells the browser to apply the XSLT style sheet specified within the tag,as follows:

<?xml-stylesheet type="text/xsl" href="stylesheetname.xsl"?>

Typically, when there is an error within XSLT itself, Internet Explorer 5 will identify the location of the error both in terms of line position, a file reference if the error occurred somewhere besides within the base XSLT structure (such as within an imported or included transformation), or by indicating variables and parameters that have either been improperly constructed or that refer to variable references that had been mistyped or not included.

One common problem that frequently arises is in misidentification of namespaces. especially with respect to XSLT the proper use of name spaces is critical to help the browser identify which transformation language it should be using for processing XML in the first place. specifically, in order to work with the current W3C XSLT implementation, the stylesheet head must include the following namespace definition, with the indicated letter case:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

If the transformation does not look like it is properly being applied to the XML (or if what gets output reflects only be XSLT structure and not the underlying XML structure) then there is probably an improper namespace definition. Additionally, unlike with the older XSL specification, the version = "1.0" attribute must be included in order to work with the structure properly.

As you become more familiar with XSLT, the errors that you create are likely to be more errors of logic rather than errors of syntax. In other words, you may have XSLT structures that are syntactically correct, but have some flaw in the logical structure. Typically, these errors occur in conditional statements - the test attributes of xsl:if and xsl:when statements,the select attribute of xsl:apply-templates and xsl:call-template, the match attribute of xsl:template, and so forth. In general, the best technique for debugging such bugs is to comment out any calling operation one statement at a time and see what causes the style sheet to break.

Another useful tool in the debugging toolbox is <xsl:message>. When placed within a style sheet (with the command's terminate attribute set to "yes") it will cause the processing to terminate and raise an error message that is caught by the ASP error handler. Thus, you could get a snapshot of what a specific variable or parameter contained, or see if the processor had reached a specific point in the code. For instance, the following code illustrates how you would determine the contents of the element title within the current book context:

<xsl:template match="book">
    <xsl:message terminate="yes">
<xsl:value-of select="title"/>
    </xsl:message>
    <!-- more code -->
</xsl:template>

You can use the JavaScript try() and catch() methods to trap errors within XSLT and display them accordingly. As an example, the following modification to the ASP main() function will indicate the error that took place formatted to follow an explanatory message:

function main(){
    var srcDocName="book_catalog.xml"
    var styleSheetName="catalogFilter.xsl";
    var srcDoc=loadSource(srcDocName);
    try{
        var processor=getProcessor(styleSheetName);
        }
    catch(e){
        Response.ContentType="text/html"
        Response.Write("An error occurred in stylesheet '" + styleSheetName + "':<br/>");
        Response.Write(e.description);
        Response.End;
        }
    Response.ContentType=getMimeType(processor);
    var genre=Request("genre");
    if(""+genre=="undefined"){
        genre="all";
        }
    else {
        genre=""+genre;
        }
    processor.addParameter("selected_genre",genre);
    transformData(srcDoc,processor);
    }

Additionally, in a similar vein to the <xsl:message> command, you can also employ the <xsl:comment> command to pass information into the output stream. This can help you see the state of variables without disrupting the flow of operation. For instance, in the catalogFilter.xsl file, adding the comment

<xsl:comment>Price=$<xsl:value-of select="price"/></xsl:comment>

into the "book" matching template will cause

<!-- Price=$3.25 -->

or something similar to appear in the HTML code – invisible to the final browsed page, but viewable in the HTML source.

See Also

Using the Default Style Sheet | Debugging a Style Sheet


Using XML Data Islands and Client-Side XSLT

XSLT running on the client can be an effective way of creating sophisticated applications that do not require the repeated downloads, complex state-management issues, and screen refreshes that characterize server-side interactions.

To use XSLT on the client you need to make sure that you have the MSXML3 parser component on the browser. Because Internet Explorer 5 and 5.5 do not ship with MSXML3, this limits your options for deploying XSLT in an open Internet environment, though it can be used effectively in some intranet environments.

One common problem when dealing with server-side XSLT comes from the inability to "disconnect" from the server to change formatting information. For example, if your web page is viewed on a laptop that's not connected to the network, you can only see the one table that was initially downloaded. By weaving both XML source and XSLT transformation into the web page in the form of data islands, you can reference the local data representations if a connection to the web is not available.

Data Islands on the client can be accessed through the dataIslandRef.XMLDocument property, where dataIslandRef is the id of the data island in question, and can be loaded into an XML DOM by passing this object to to the DOM's .load method. Once loaded in this fashion, manipulating the DOM is identical to manipulating the DOM as if the document was loaded from a file, with the sole exception that you cannot save back to a data island that was instantiated within the web page. In other words, if the <XML> element that contains the data island didn't retrieve this information through a src attribute, then you can't update that data island.

The file DataIsland.htm sample file illustrates the same component as was shown in Using ASP with XSLT Processor and Template Objects, a genre-ordered catalog, but in this code, the XML source, the XSLT transformation and the operational JavaScript code are all part of the web page. For more information, see Sample HTML File for XML Data Islands.

In the DataIsland.htm sample file, the JavaScript code for transforming the XSLT is quite similar to the code used in the server version in Using ASP with XSLT Processor and Template Objects, but there are a few notable differences. The showGenre() function (renamed from main() in the server version) takes the genre name as a parameter, which lets it modify the contents of a DIV element (called catalog_table) when the select list box's value is changed. This function passes references to the two data islands book_catalog and catalog_filter directly, rather than passing file names. The transformData() function returns the resultant transformed data as an XML object rather than sending the output to the Response object, because while the Server.Response object can take an XML DOM stream as input, the innerHTML command cannot – it can only take a string.

Both loadSource() and getProcessor() have also been modified to take into account the data island source of the information, and getProcessor now uses a local variable to store the XSLT processor object rather than a session variable, but otherwise the two are quite similar. The only changes that was made in the XSLT in Using ASP with XSLT Processor and Template Objects was to contain the result in a <DIV> element rather than in the full <HTML> wrapper (as this has already been declared on the client), to move the style sheet out to the containing HTML document to simplify code, and to change the onchange attribute of the <SELECT> list box from a URL call to the command showGenre(this.value), which will update the table to reflect the selected genre.

This points up a number of facets about working with XSLT on the client:

  • The JavaScript functions discussed here are highly modular, with only the showGenre function actually containing code specific to a single style sheet and data source. By maintaining this modularity, you can create other functions that use different sources or transformations in the same page – a navigation bar, for instance, or a menu -- without needing to have separate functions that transform each component separately.
  • You can use the src attribute on data islands to load both data and transformations from the server in response to changing conditions on the client. For instance, an XML document containing sales figures could have a default table translation, but could be converted into a chart by changing the src attribute of the transformation data island to reflect a chart.xsl document on the server, then the transformation applied using the same interface as described above. Similarly, live data from a SQL Server 2000 URL call could be retrieved into a data island via the src attribute (the specific parameters determined from form elements) and from there could be reformatted by the existing transformation on the client.
  • Use parameters in the XSLT transformation to change the nature of the transformation – don't try modifying the style sheet directly. A stylesheet's parameters are very much like the public properties of a COM object – they represent an interface into the style sheet, which otherwise should be treated as a black box.


Sample HTML File for XML Data Islands

HTML File (DataIsland.htm)

<html>
<head>
   <title>Untitled</title>
    <style>
        .catalog_genre_head {background-color:darkGreen;font-size:24pt;color:white;font-family:Impact;}
        .catalog_head {background-color:green;font-size:18pt;color:white;font-family:Impact;}
        .catalog_row0 {background-color:lightGreen;}
        .catalog_row1 {background-color:white;}
        .catalog_row_end {background-color:darkGreen;}
    </style>
</head>

<body>
<h1>Scobie Press Book Catalog</h1>
<p>Select a genre to see all books in that genre:</p>
<div id="catalog_table"></div>

<xml id="book_catalog">
<catalog>
   <book id="bk101">
      <title>XML Developer's Guide</title>
      <author>Gambardella, Matthew</author>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications with XML.</description>
   </book>
   <book id="bk102">
      <title>Midnight Rain</title>
      <author>Ralls, Kim</author>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description>
   </book>
   <book id="bk103">
      <title>Maeve Ascendant</title>
      <author>Corets, Eva</author>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-11-17</publish_date>
      <description>After the collapse of a nanotechnology society in England, the young survivors lay the foundation for a new society.</description>
   </book>
   <book id="bk104">
      <title>Oberon's Legacy</title>
      <author>Corets, Eva</author>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2001-03-10</publish_date>
      <description>In post-apocalypse England, the mysterious agent known only as Oberon helps to create a new life for the inhabitants of London. Sequel to Maeve Ascendant.</description>
   </book>
   <book id="bk105">
      <title>The Sundered Grail</title>
      <author>Corets, Eva</author>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2001-09-10</publish_date>
      <description>The two daughters of Maeve, half-sisters, battle one another for control of England. Sequel to Oberon's Legacy.</description>
   </book>
   <book id="bk106">
      <title>Lover Birds</title>
      <author>Randall, Cynthia</author>
      <genre>Romance</genre>
      <price>4.95</price>
      <publish_date>2000-09-02</publish_date>
      <description>When Carla meets Paul at an ornithology conference, tempers fly as feathers get ruffled.</description>
   </book>
   <book id="bk107">
      <title>Splish Splash</title>
      <author>Thurman, Paula</author>
      <genre>Romance</genre>
      <price>4.95</price>
      <publish_date>2000-11-02</publish_date>
      <description>A deep sea diver finds true love twenty thousand leagues beneath the sea.</description>
   </book>
   <book id="bk108">
      <title>Creepy Crawlies</title>
      <author>Knorr, Stefan</author>
      <genre>Horror</genre>
      <price>4.95</price>
      <publish_date>2000-12-06</publish_date>
      <description>An anthology of horror stories about roaches, centipedes, scorpions  and other insects.</description>
   </book>
   <book id="bk109">
      <title>Paradox Lost</title>
      <author>Kress, Peter</author>
      <genre>Science Fiction</genre>
      <price>6.95</price>
      <publish_date>2000-11-02</publish_date>
      <description>After an inadvertant trip through a Heisenberg Uncertainty Device, James Salway discovers the problems of being quantum.</description>
   </book>
   <book id="bk110">
      <title>Microsoft .NET: The Programming Bible</title>
      <author>O'Brien, Tim</author>
      <genre>Computer</genre>
      <price>36.95</price>
      <publish_date>2000-12-09</publish_date>
      <description>Microsoft's .NET initiative is explored in detail in this deep programmer's reference.</description>
   </book>
   <book id="bk111">
      <title>MSXML3: A Comprehensive Guide</title>
      <author>O'Brien, Tim</author>
      <genre>Computer</genre>
      <price>36.95</price>
      <publish_date>2000-12-01</publish_date>
      <description>The Microsoft MSXML3 parser is covered in detail, with attention to XML DOM interfaces, XSLT processing, SAX and more.</description>
   </book>
   <book id="bk112">
      <title>Visual Studio 7: A Comprehensive Guide</title>
      <author>Galos, Mike</author>
      <genre>Computer</genre>
      <price>49.95</price>
      <publish_date>2001-04-16</publish_date>
      <description>Microsoft Visual Studio 7 is explored in depth, looking at how Visual Basic, Visual C++, C#, and ASP+ are integrated into a comprehensive development environment.</description>
   </book>
</catalog>
</xml>

<xml id="catalog_filter">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt"
        version="1.0">

        <xsl:output method="xml" omit-xml-declaration="yes"/>

        <xsl:param name="selected_genre" select="'all'"/>

        <xsl:template match="/">
                <div>
                    <form method="post" action="catalog.asp">
                    Genre
                    <select name="genre" value="{$selected_genre}" onchange="showGenre(this.value)">
                        <option value="all"><xsl:if test="$selected_genre='all'"><xsl:attribute name="selected">Selected</xsl:attribute></xsl:if>All</option>
                        <option value="Computer"><xsl:if test="$selected_genre='Computer'"><xsl:attribute name="selected">Selected</xsl:attribute></xsl:if>Computer</option>
                        <option value="Fantasy"><xsl:if test="$selected_genre='Fantasy'"><xsl:attribute name="selected">Selected</xsl:attribute></xsl:if>Fantasy</option>
                        <option value="Horror"><xsl:if test="$selected_genre='Horror'"><xsl:attribute name="selected">Selected</xsl:attribute></xsl:if>Horror</option>
                        <option value="Romance"><xsl:if test="$selected_genre='Romance'"><xsl:attribute name="selected">Selected</xsl:attribute></xsl:if>Romance</option>
                        <option value="Science Fiction"><xsl:if test="$selected_genre='Science Fiction'"><xsl:attribute name="selected">Selected</xsl:attribute></xsl:if>Science Fiction</option>
                    </select>
                    </form>
                    <br/>
                    <xsl:apply-templates select="catalog"/>
            </div>
        </xsl:template>

        <xsl:template match="catalog">
            <table class="catalog_table">
                <xsl:apply-templates select="book[($selected_genre='all') or ($selected_genre=./genre)]">
                    <xsl:sort select="title"/>
                </xsl:apply-templates>
            </table>
        </xsl:template>

        <xsl:template match="book">
            <xsl:if test="position()=1">
            <tr class="catalog_genre_head"><td colspan="6">
            <xsl:choose>
            <xsl:when test="$selected_genre='all'">
            All Genres
            </xsl:when>
            <xsl:otherwise>
            Genre: <xsl:value-of select="genre"/>
            </xsl:otherwise>
            </xsl:choose>
            </td></tr>
            <tr class="catalog_head">
                <td>#</td>
                <td>Title</td>
                <td>Author</td>
                <td>Publication Date</td>
                <td>Description</td>
                <xsl:if test="$selected_genre='all'">
                <td>Genre</td>
                </xsl:if>
            </tr>
            </xsl:if>
            <tr class="catalog_row{position() mod 2}">
                <td><xsl:value-of select="position()"/></td>
                <td class="catalog_cell"><xsl:value-of select="title"/></td>
                <td class="catalog_cell"><xsl:value-of select="author"/></td>
                <td class="catalog_cell"><xsl:value-of select="publish_date"/></td>
                <td class="catalog_cell"><xsl:value-of select="description"/></td>
                <xsl:if test="$selected_genre='all'">
                <td class="catalog_cell"><xsl:value-of select="genre"/></td>
                </xsl:if>
            </tr>
            <xsl:if test="position()=last()">
            <tr class="catalog_row_end"><td colspan="6"> </td></tr>
            </xsl:if>
        </xsl:template>
    </xsl:stylesheet>
</xml>

<script language="JavaScript">
function loadSource(sourceObj){
    var xmlDoc=new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
    xmlDoc.async=false;
    xmlDoc.load(sourceObj.XMLDocument);
    return xmlDoc;
    }

var table_proc=null;

function getProcessor(transformObj){
    if (table_proc==null){
        var xslDoc=new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
        var xslTemplate=new ActiveXObject("MSXML2.XSLTemplate");
        xslDoc.async=false;
        xslDoc.load(transformObj.XMLDocument);
        xslTemplate.stylesheet=xslDoc;
        xslProcessor=xslTemplate.createProcessor();
        table_proc=xslProcessor;
        }
    else {
        xslProcessor=table_proc;
        }
    return xslProcessor;
    }

function transformData(srcDoc,processor){
    var resultDoc=new ActiveXObject("MSXML.DOMDocument");
    processor.input=srcDoc;
    processor.output=resultDoc;
    processor.transform();
    return resultDoc;
    }

function showGenre(genre){
    var srcDoc=loadSource(book_catalog);
    var processor=getProcessor(catalog_filter);
    processor.addParameter("selected_genre",genre);
    var rsltDoc=transformData(srcDoc,processor);
    catalog_table.innerHTML=rsltDoc.xml
    }

showGenre("all");

</script>

</body>
</html>


Controlling Output Format with the media-type Attribute

XSLT uses the <xsl:output> command to determine whether the output produced by the transformation is conformant XML (<xsl:output method="xml"/>), valid HTML (<xsl:output method="html"/>) or unverified text (<xsl:output method="text"/>). However, this can cause some problems with versioning, especially on the server, since IIS automatically sets the output of ASP files to a mime-type of text/html, insuring that the browser interprets the material sent to it as web pages. Moreover, while these types can shape the necessary headers (or lack thereof), simply because a given document is in XML format is not necessarily enough to identify its output type: a graphic file may be in Scalable Vector Graphics format, for instance, or a Wireless message may be in WML format. These essentially need to inform ASP that they are both of type XML and have the appropriate mime type (such as image/svg for SVG or text/vnd.wap.wml for WML).

The <xsl:output> command includes one additional attribute, however, called media-type. This attribute is not used directly by the XSLT parser in generating output, but it can be read from the style sheet through the DOM and used to set the Response.ContentType property. ContentType creates a header in the returning HTTP message that informs the browser about how it should handle given mime-types. Thus, in the following style sheet:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" media-type="text/vnd.wap.wml"/>

<xsl:template match="/"/>

</xsl:stylesheet>

the media-type indicates that the output from the style-sheet should be a WML document (text/vnd.wap.wml). The function getMimeType() takes an XSLT processor object and retrieves the mime-type from the <xsl:output> node (the full code is in catalog.asp, in Sample ASP Script for XSLT Processor Objects).

function getMimeType(processor){
    var stylesheet=processor.stylesheet;
    var localTypeNode=stylesheet.selectSingleNode("//xsl:output/@media-type");
    if (""+localTypeNode=="undefined"){
        var localMethodNode=stylesheet.selectSingleNode("//xsl:output/@method");
        if (""+localMethodNode =="undefined"){
            mimeType="text/html";
            }
        else {
            localMethodName=localMethodNode.text;
            switch(localMethodName){
                case "text":mimeType="text/plain";break;
                case "html":mimeType="text/html";break;
                case "xml":mimeType="text/xml";break;
                }
            }
        }
    else {
        mimeType=localTypeNode.text;
        }
    return mimeType;
    }

The Content/Type can then be set simply by assigning the result of the getMimeType function to it:

Response.ContentType=getMimeType(processor)


Extending XSLT

The XSLT specification does not explicitly deal with mechanisms to extend XSLT, leaving that role instead to the XSLT parser vendors. Because there are numerous places where extending XSLT is not only useful but also potentially necessary, this ambiguity has meant that there are a number of different, though similar, mechanisms for doing this.

MSXML 3.0 offers two distinct solutions for extending XSLT:

  • The MSXML: Namespace – This namespace is used by Microsoft to add scripting support (via the <msxsl:script> element), as well as provide a few system additions, such as msxsl:node-set() for converting XML Tree Fragments into node sets.
  • The .addObject Method – This object, part of the IXSLProcessor interface, lets users associate an object with a namespace and then access the objects properties and methods from within the stylesheet.

This section also covers the following:

  • Adding COM Objects to Extend XSLT

Creating an extension within an XSLT document requires three parts – declaring the namespace for the extension in the appropriate scope of the document (typically in the <xsl:stylesheet node), defining the extensions via an <msxsl:script> block within the document, and invoking the functions defined later within the style sheet itself.

The msxsl: namespace is included in the XSLT processor to support a number of "semi-standard" functions, such as the msxsl:node-set() function, that are too useful to not include and that are generally found in other implementations of the XSLT parser. Additionally, the namespace establishes the msxsl:script element which allows XSLT developers to create their own set of XPath-like functions implemented using scripting languages such as EcmaScript or VBScript. However, any scripting language can be invoked within a script block so long as the library for that language exists on the calling system – thus it is possible to create namespace methods written in Perl or Python, as two of many possible examples.

One of the principle purposes of such extensions is to interface with some other aspect of the system – accessing ADSi, a voice interface, or the file system, for instance. The last example provides a good case study for demonstrating how such extensions may be written. A useful application would be for an interface that would convert file directory structures into XML – the folder and file structures of a typical file system directory can easily be modeled using the container/contained relationships of XML. While there is no explicit component that can convert such a listing into XML, you can use the Scripting File System Object to retrieve properties about both files and folders, such as the date the file was created or last accessed, the file size, the file type, and both the long (normal) and short (8.3 character filename) paths for each file or folder. Moreover, with a few simple routines, you can echo the directory structure with XML, where each folder element contains child file and folder elements, the latter of which containing their own files and folders, and so forth.

The directory.xsl style sheet below demonstrates one implementation of such a file system to XML converter, and serves as a good reference document for creating such extensions. The <xsl:stylesheet> element itself includes three elements that much be present for extensions to work property. The xmlns:msxsl namespace attribute much be given, and must be set to urn:schemas-microsoft-com:xslt.

The second namespace, the xmlns:fs namespace, should be set to a unique URI that is exclusive to this particular domain – in this case, the URI urn:schemas-microsoft-com:filesystem. It should be noted that the specific prefix is not necessarily tied into the namespace – fs, is used here, but it could just as readily be flr: or dir: or some other namespace prefix.

Finally, the prefixes for all extensions should be declared as white space separated name tokens. In the case of directory.xsl, there are two specific namespaces defined, with prefixes msxsl and fs respectively.

Once these prefixes are specified, you need to implement the interfaces that will be available through the fs: namespace. This is handled through the <msxsl:script> element, which should also include both the language attribute to set which scripting language you are using and the implements-prefix attribute which gives the prefix that you're writing code for.

The functions that are defined within the script block act essentially as methods to the namespace "object". In this particular implementation there are only two real public functions. The first, getFolder(), which retrieves either the indicated folder and all of its relative subfolders (mode=0), the folder and all the files that the folder contains (mode=1), or the whole tree of files and folders relative to the indicated directory (mode=2). The second function, fileCount() performs a quick count of the number of files without creating an XML structure to hold them.

The getFolder() function in directory.xsl returns a very simple XML structure with only folder and file nodes, where each node contains attributes that provide more detailed information about the file in question. Typical output might look something like this:

<folder name="MSDN"
path="C:\MSDN"
dateCreated="2000-09-09"
dateLastAccessed="2000-09-26"
shortName="msdn"
shortPath="C:\msdn"
size="20917180"
type="File Folder">
<file name="createMLSDocs.asp"
path="C:\MSDN\createMLSDocs.asp"
dateCreated="2000-09-10"
dateLastAccessed="2000-09-26"
shortName="CREATE~1.ASP"
shortPath="C:\msdn\CREATE~1.ASP"
size="1030"
type="ASP auto file">
</file>
<file name="Handling White Space.doc"
path="C:\MSDN\Handling White Space.doc"
dateCreated="2000-09-11"
dateLastAccessed="2000-09-12"
shortName="HANDLI~1.DOC"
shortPath="C:\msdn\HANDLI~1.DOC"
size="40960"
type="Microsoft Word Document">
</file>
<!-- additional folders and files -->
</folder>

The transformation given here does not contain any root node match – it is designed strictly to include as part of another XSLT style sheet. For example, one application for this kind of routine would be to generate an explorer view outline of a folder with all of its child folders and files. By including the fs extension, you could essentially build a complete XML tree of the file structure in question then from this structure create the outline using HTML LIst elements. Note that if your directory structure does not change frequently, you could also generate this XML structure and cache it, so that the routine that builds the structure (a relatively slow process) can be performed independently of the calls to retrieve and display the structure. The stylesheet outlineDraw invokes the getFolder() function, passing parameters from a simple XML file called rootNode.xml which has only a single element:

rootNode.xml

<?xml version='1.0'?>
<root href="c:\msdn" mode="2"/>

The outlineDraw.xsl file itself requires the same namespace and extension element prefixes that the Directory.xsl file does in order to work, but the actual implementation comes from the latter file. If invokes the getFolder() function and stores the resulting XML file in a local variable called $root_folder, which can then be manipulated in a manner similar to that of the primary input stream. The file outlineDraw.xsl is shown in Sample Auxiliary XSLT File for Extending XSLT.

You can use an ASP file similar to the catalog_filter of Using ASP with XSLT Processor and Template Objects to generate the HTML output, as shown in the following file: showDirectory.asp in Sample ASP File for Generating HTML for Extending XSLT.

Sample Files for This Topic

Sample XSLT File for Extending XSLT (directory.xsl)

Sample Auxiliary XSLT File for Extending XSLT (outlineDraw.xsl)

Sample ASP File for Generating HTML for Extending XSLT (showDirectory.asp)

After the above sample files, this section continues with the following alternative approach:

  • Adding COM Objects to Extend XSLT


Sample XSLT File for Extending XSLT

XSLT File (directory.xsl)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:fs="urn:schemas-microsoft-com:filesystem"
    extension-element-prefixes="fs msxsl"
    version="1.0">

    <msxsl:script language="VBScript" implements-prefix="fs">'<![CDATA[
    dim fs
    dim FoldersOnly
    dim FilesOnly
    dim FilesAndFolders

    function getFolder(dirName,mode)
        dim folder
        init
        set folder=fs.getFolder(dirName)
        set folderDoc=createObject("MSXML2.FreeThreadedDOMDocument")
        folderDoc.setProperty "SelectionLanguage","XPath"
        folderDoc.async=false
        folderDoc.loadXML "<folder name='"+dirName+"'/>"
        set folderNode=folderDoc.documentElement
        folderNode.setAttribute "name",folder.name
        folderNode.setAttribute "path",folder.path
        folderNode.setAttribute "dateCreated",mapDate(folder.dateCreated)
        folderNode.setAttribute "dateLastAccessed",mapDate(folder.dateLastAccessed)
        folderNode.setAttribute "shortName",folder.shortName
        folderNode.setAttribute "shortPath",folder.shortPath
        folderNode.setAttribute "size",folder.size
        folderNode.setAttribute "type",folder.type
        if mode=FoldersOnly or mode=FilesAndFolders then
            getFolders folder,folderNode,dirName,mode
        end if
        if mode=FilesOnly or mode=FilesAndFolders then
            getFiles folder,folderNode,dirName
        end if
        'set getFolder=folderNode
        set getFolder=folderDoc
    end function

    function fileCount(dirName)
       dim folder
       set folder=fs.getFolder(dirName)
       fileCount=folder.files.count
    end function

    function init()
        if fs=0 then
            set fs=createObject("Scripting.FileSystemObject")
            FoldersOnly=0
            FilesOnly=1
            FilesAndFolders=2
        end if
    end function

    function folderExists(dirName)
        folderExists=fs.folderExists(dirName)
    end function

    function getFiles(parentFolder,folderDoc,dirName)
        for each file in parentFolder.files
            set fileNode=folderDoc.ownerDocument.createElement("file")
            fileNode.setAttribute "name",file.name
            fileNode.setAttribute "path",file.path
            fileNode.setAttribute "dateCreated",mapDate(file.dateCreated)
            fileNode.setAttribute "dateLastAccessed",mapDate(file.dateLastAccessed)
            fileNode.setAttribute "shortName",file.shortName
            fileNode.setAttribute "shortPath",file.shortPath
            fileNode.setAttribute "size",file.size
            fileNode.setAttribute "type",file.type
            folderDoc.appendChild fileNode
        next
        getFiles=parentFolder.files.count
    end function

    function mapDate(dateStr)
        dt=split(dateStr," ")(0)
        dtStr=cstr(Year(dt)) & "-" & right("0" & Month(dt),2) & "-" & right("0" &Day(dt),2)
        mapDate=dtStr
    end function

    function getFolders(parentFolder,folderDoc,dirName,mode)
        for each folder in parentFolder.subfolders
            set folderNode=folderDoc.ownerDocument.createElement("folder")
            folderNode.setAttribute "name",folder.name
            folderNode.setAttribute "path",folder.path
            folderNode.setAttribute "dateCreated",mapDate(folder.dateCreated)
            folderNode.setAttribute "dateLastAccessed",mapDate(folder.dateLastAccessed)
            folderNode.setAttribute "shortName",folder.shortName
            folderNode.setAttribute "shortPath",folder.shortPath
            folderNode.setAttribute "size",folder.size
            folderNode.setAttribute "type",folder.type
            folderDoc.appendChild folderNode
            getFolders folder,folderNode,folder.path, mode
            if mode=FilesAndFolders then
                getFiles folder,folderNode,folder.path
            end if
        next
        getFolders=parentFolder.subfolders.count
    end function
']]>    </msxsl:script>
</xsl:stylesheet>


Sample Auxiliary XSLT File for Extending XSLT

XSLT File (outlineDraw.xsl)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:fs="urn:schemas-microsoft-com:filesystem"
    extension-element-prefixes="fs msxsl"
    version="1.0">
    <xsl:include href="Directory.xsl"/>
    <xsl:output method="html" media-type="text/html"/>

    <xsl:template match="/">
    <xsl:variable name="root_folder" select="fs:getFolder(string(root/@href),number(root/@mode))"/>
    <xsl:variable name="outline_mode" select="root/@mode"/>
    <html>
        <head>
            <title>Directory Tree</title>
            <style>
            .file {list-style-image:url(graphics/sitegraphics/file.gif);}
            .folder {list-style-image:url(graphics/sitegraphics/folder.gif);}
            </style>
        </head>
        <body>
        <xsl:copy-of select="$root_folder"/>
        <h1>Directory Tree</h1>
        <ul>
            <xsl:apply-templates select="$root_folder/folder">
                <xsl:with-param name="outline_mode" select="$outline_mode"/>
            </xsl:apply-templates>
        </ul>
        </body>
        </html>
    </xsl:template>

    <xsl:template match="folder">
        <xsl:param name="outline_mode"/>
        <li class="folder"><xsl:value-of select="@name"/>
            <xsl:if test="folder and ($outline_mode=0 or $outline_mode=2)">
                <ul>
                    <xsl:apply-templates select="folder">
                        <xsl:with-param name="outline_mode" select="$outline_mode"/>
                    </xsl:apply-templates>
                </ul>
            </xsl:if>
            <xsl:if test="file and ($outline_mode=1 or $outline_mode=2)">
                <ul>
                    <xsl:apply-templates select="file"/>
                </ul>
            </xsl:if>
        </li>
    </xsl:template>

    <xsl:template match="file">
        <li class="file"><xsl:value-of select="@name"/></li>
    </xsl:template>

</xsl:stylesheet>


Sample ASP File for Generating HTML for Extending XSLT

ASP File (showDirectory.asp)

<%@LANGUAGE="JavaScript"%>
<%Response.expires=-1;
'showDirectory.asp
'Sorts books from a given catalog by title, for a given Genre.
function loadSource(sourceName){
    var xmlDoc=new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
    xmlDoc.async=false;
    xmlDoc.load(Server.mapPath(sourceName));
    return xmlDoc;
    }

function getProcessor(transformName){
    if ("" + Session(transformName) == "undefined"){
        var xslDoc=new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
        var xslTemplate=new ActiveXObject("MSXML2.XSLTemplate");
        xslDoc.async=false;
        xslDoc.load(Server.mapPath(transformName));
        xslTemplate.stylesheet=xslDoc;
        xslProcessor=xslTemplate.createProcessor();
        Session(transformName)=xslProcessor;
        }
    else {
        xslProcessor=Session(transformName);
        }
    return xslProcessor;
    }

function transformData(srcDoc,processor){
    processor.input=srcDoc;
    processor.output=Response;
    processor.transform();
    return true;
    }

function main(){
    var srcDoc=loadSource("root_folder.xml");
    var processor=getProcessor("outlineDraw.xsl");

    transformData(srcDoc,processor);
    }

main();
 %>


Adding COM Objects to Extend XSLT

The approach described in the topic Extending XSLT is powerful, but it has the disadvantage that any scripting solution has – it uses interpreted code that can be quite slow, especially if it has to query some external device to work. While intelligent design can effectively segregate the slow operations (querying and generating raw XML) from the more rapid ones (transforming and filtering), turning slow interpreted code that has to work across process boundaries into faster compiled code can minimize the impact that such extensions will have on performance.

The AddObject method lets you associate COM objects that can form a bridge between the XSLT style sheet and the rest of the operating system. Because of the complexity of building such a bridge and the way that the component has been designed, the objects that you add need to be designed so that their interface data types conform to XML data types – strings, numbers, nodes, node-sets, and DOMs. As a consequence, you can use very few COM objects off the shelf, but you can create COM or COM+ wrappers that expose the proper interface types. Additionally, such objects have to be flat – a wrapper class cannot reference child classes.

The Directory.xsl VBS code can easily be moved into a Visual Basic ActiveX Class with almost no modification, as given in the Directory Class listing in Sample Directory Class for Extending XSLT with COM.

Setting the project names to MSDNXSLTSamples in Visual Basic, the file can be compiled and registered, making it accessible as a COM object with progID MSDNXSLTSamples.Directory. Once compiled, this object can then be referenced by the AddObject method, as shown in showDirectory2.asp (Sample ASP File for Extending XSLT with COM).

The XSLT file needs to change slightly – because the object is being defined externally through a COM object rather than through an internal XSLT script, there is no need to import the directory.xsl file. Other than that, the namespace definitions and extension information in the header are identical, in outlineDraw2.xsl (Sample XSLT File for Extending XSLT with COM).

These files are used by outlineDraw2.xsl:

File.gif:

Folder.gif:


Sample Directory Class for Extending XSLT with COM

    ' Directory Class
    dim fs as New File System Object
    dim FoldersOnly
    dim FilesOnly
    dim FilesAndFolders

    Public Function getFolder(dirName as String,mode as Integer) as FreeThreadedDOMDocument
        dim folder as FileSystemObject.Folder
     dim folderDoc as FreeThreadedDOMDocument
        dim folderNode as IXMLDOMElement
        init
        set folder=fs.getFolder(dirName)
        set folderDoc=new FreeThreadedDOMDocument
        folderDoc.setProperty "SelectionLanguage","XPath"
        folderDoc.async=false
        folderDoc.loadXML "<folder name='"+dirName+"'/>"
        set folderNode=folderDoc.documentElement
        folderNode.setAttribute "name",folder.name
        folderNode.setAttribute "path",folder.path
        folderNode.setAttribute "dateCreated",mapDate(folder.dateCreated)
        folderNode.setAttribute "dateLastAccessed",mapDate(folder.dateLastAccessed)
        folderNode.setAttribute "shortName",folder.shortName
        folderNode.setAttribute "shortPath",folder.shortPath
        folderNode.setAttribute "size",folder.size
        folderNode.setAttribute "type",folder.type
        if mode=FoldersOnly or mode=FilesAndFolders then
            getFolders folder,folderNode,dirName,mode
        end if
        if mode=FilesOnly or mode=FilesAndFolders then
            getFiles folder,folderNode,dirName
        end if
        set getFolder=folderDoc
    End Function

    Public Function fileCount(dirName) as Long
       dim folder
       set folder=fs.getFolder(dirName)
       fileCount=folder.files.count
    End Function

    function init()
        if fs=0 then
            set fs=new Scripting.FileSystemObject
            FoldersOnly=0
            FilesOnly=1
            FilesAndFolders=2
        end if
    end function

    function folderExists(dirName as String) as Boolean
        folderExists=fs.folderExists(dirName)
    end function

    function getFiles(parentFolder as FileScriptingObject.Folder,folderDoc as IXMLDOMElement,dirName as String) as Long
     dim file as FileScriptingObject.File
        dim fileNode as IXMLDOMElement
        for each file in parentFolder.files
            set fileNode=folderDoc.ownerDocument.createElement("file")
            fileNode.setAttribute "name",file.name
            fileNode.setAttribute "path",file.path
            fileNode.setAttribute "dateCreated",mapDate(file.dateCreated)
            fileNode.setAttribute "dateLastAccessed",mapDate(file.dateLastAccessed)
            fileNode.setAttribute "shortName",file.shortName
            fileNode.setAttribute "shortPath",file.shortPath
            fileNode.setAttribute "size",file.size
            fileNode.setAttribute "type",file.type
            folderDoc.appendChild fileNode
        next
        getFiles=parentFolder.files.count
    end function

    function mapDate(dateStr as String) as String
     dim dt as String
        dim dtStr as String
        dt=split(dateStr," ")(0)
        dtStr=cstr(Year(dt)) & "-" & right("0" & Month(dt),2) & "-" & right("0" &Day(dt),2)
        mapDate=dtStr
    end function

    function getFolders(parentFolder as FileSystemObject.Folder,folderDoc as IXMLDOMElement,dirName as String,mode as Long) as Long
     dim folder as FileScriptingObject.Folder
        dim folderNode as IXMLDOMElement
        for each folder in parentFolder.subfolders
            set folderNode=folderDoc.ownerDocument.createElement("folder")
            folderNode.setAttribute "name",folder.name
            folderNode.setAttribute "path",folder.path
            folderNode.setAttribute "dateCreated",mapDate(folder.dateCreated)
            folderNode.setAttribute "dateLastAccessed",mapDate(folder.dateLastAccessed)
            folderNode.setAttribute "shortName",folder.shortName
            folderNode.setAttribute "shortPath",folder.shortPath
            folderNode.setAttribute "size",folder.size
            folderNode.setAttribute "type",folder.type
            folderDoc.appendChild folderNode
            getFolders folder,folderNode,folder.path, mode
            if mode=FilesAndFolders then
                getFiles folder,folderNode,folder.path
            end if
        next
        getFolders=parentFolder.subfolders.count
    end function


Sample ASP File for Extending XSLT with COM

ASP File (showDirectory2.asp)

<%@LANGUAGE="JavaScript"%>
<%Response.expires=-1;
'showDirectory2.asp
'Sorts books from a given catalog by title, for a given Genre.
function loadSource(sourceName){
    var xmlDoc=new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
    xmlDoc.async=false;
    xmlDoc.load(Server.mapPath(sourceName));
    return xmlDoc;
    }

function getProcessor(transformName){
    if ("" + Session(transformName) == "undefined"){
        var xslDoc=new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
        var xslTemplate=new ActiveXObject("MSXML2.XSLTemplate");
        xslDoc.async=false;
        xslDoc.load(Server.mapPath(transformName));
        xslTemplate.stylesheet=xslDoc;
        xslProcessor=xslTemplate.createProcessor();
        Session(transformName)=xslProcessor;
        }
    else {
        xslProcessor=Session(transformName);
        }
    return xslProcessor;
    }

function transformData(srcDoc,processor){
    processor.input=srcDoc;
    processor.output=Response;
    processor.transform();
    return true;
    }

function main(){
    dim dirObj
    set dirObj=Server.createObject("MSDNXSLTSamples.Directory")
    var srcDoc=loadSource("root_folder.xml");
    var processor=getProcessor("outlineDraw2.xsl");
    processor.addObject dirObj, "urn:schemas-microsoft-com:filesystem"
    transformData(srcDoc,processor);
    }

main();
 %>


Sample XSLT File for Extending XSLT with COM

XSLT File (outlineDraw2.xsl)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:fs="urn:schemas-microsoft-com:filesystem"
    extension-element-prefixes="fs msxsl"
    version="1.0">
    <xsl:output method="html" media-type="text/html"/>

    <xsl:template match="/">
    <xsl:variable name="root_folder" select="fs:getFolder(string(root/@href),number(root/@mode))"/>
    <xsl:variable name="outline_mode" select="root/@mode"/>
    <html>
        <head>
            <title>Directory Tree</title>
            <style>
            .file {list-style-image:url(graphics/sitegraphics/file.gif);}
            .folder {list-style-image:url(graphics/sitegraphics/folder.gif);}
            </style>
        </head>
        <body>
        <xsl:copy-of select="$root_folder"/>
        <h1>Directory Tree</h1>
        <ul>
            <xsl:apply-templates select="$root_folder/folder">
                <xsl:with-param name="outline_mode" select="$outline_mode"/>
            </xsl:apply-templates>
        </ul>
        </body>
        </html>
    </xsl:template>

    <xsl:template match="folder">
        <xsl:param name="outline_mode"/>
        <li class="folder"><xsl:value-of select="@name"/>
            <xsl:if test="folder and ($outline_mode=0 or $outline_mode=2)">
                <ul>
                    <xsl:apply-templates select="folder">
                        <xsl:with-param name="outline_mode" select="$outline_mode"/>
                    </xsl:apply-templates>
                </ul>
            </xsl:if>
            <xsl:if test="file and ($outline_mode=1 or $outline_mode=2)">
                <ul>
                    <xsl:apply-templates select="file"/>
                </ul>
            </xsl:if>
        </li>
    </xsl:template>

    <xsl:template match="file">
        <li class="file"><xsl:value-of select="@name"/></li>
    </xsl:template>

</xsl:stylesheet>


Using Design Patterns for XSLT

After the Introduction to Design Patterns for XSLT, this section covers the following types of design patterns:

Pattern | Description | Topic
Template Patterns | The Identity Template and its variations work by duplicating all nodes that are not otherwise handled. It is the foundation for nearly all "document" type stylesheets. | Designing Template Rules
Using Variable Patterns | This pattern uses variables and parameters to hold generated XML. This is especially useful for creating interim states within XSLT structures. | Design Patterns for Using Variables and Parameters
Class Patterns | This pattern uses named templates to create "class implementations". It is especially useful for creating frameworks. | Class Patterns: Using <xsl:import> and <xsl:include>
Linking Patterns | This pattern links multiple documents together using the document() function, either for immediate output or further processing. | Linking Patterns: Reading XML Files Using document()
Extension Patterns | This pattern utilizes the XSLT extension mechanism to add functions into the XSLT environment. This can be especially useful for adding things like ADO connections, regular expressions, the file system object and so forth. | Design Patterns for Scripting and Extension Functions

This section finishes with Using Template Patterns for Common Transformations.


Introduction to Design Patterns for XSLT

Patterns are the foundation upon which most of programming rests, yet the notion that you can utilize patterns in more than an ad hoc fashion has only really become current in the last few years. Once you understand the ways that you can harness patterns for your own purposes, you can make XSLT that is compact, powerful, and dynamic. However, before looking for XML based patterns, its often helpful to identity what exactly a pattern is:

  • Recurrent - A pattern is a repeated action, phenomena, or characteristic in a medium. Such patterns are not necessarily regular, and typically the more interesting patterns will often appear as variations upon a theme, but in general when setting up similar conditions produce a similar result, then you have a pattern you can work with.
  • Generic - A pattern, to be useful, must be able to be abstracted beyond a specific instance. In this sense, most functions are the encoding of patterns. Genericness in pattern matching is useful, since the more generic you can make a pattern, the more it can be used in different situations. However, it should be noted that genericizing patterns often also reduces performance or efficiency, so when you are trying to extend a pattern you should watch out for any such hidden costs.
  • Rich - We communicate via patterns and the richness of a pattern, the degree it departs from regularity, can determine the utility of such a pattern -- too regular, and it encodes no information, not regular enough, it can't be abstracted. This holds true for programming as much as speech, and in a pattern matching language like XSLT it can have an impact upon both the size and the complexity of the process.
  • Systemic - Patterns typically occur over an entire system among the interaction of components. Thus, the component viewpoint, where your programming effort is oriented around the actions of components, is often a poor one for spotting patterns. Declarative languages, on the other hand, tend to make patterns obvious.
  • Emergent - A useful pattern typically emerges only after a system reaches a certain level of complexity. This has to do with the fact that patterns are very much tied into the interaction of components rather than the components themselves, and as the number of interactions increase, so do apparent trends.

XSLT as a Pattern-Matching Language

XSLT is, at its core, a language for matching the node-tree structure of XML, although it also has rudimentary string matching and manipulation functions. The ability to match relationships between nodes means that you can abstract the creation of specific types of templates so that they can be made generic, matching similar structures that may have different tag names. As such, XSLT has a number of characteristics that facilitate matching:

  • Recursive - A template within XSLT can invoke itself directly or indirectly, through the use of the <xsl:apply-templates/>, <xsl:for-each/> or <xsl:call-template/> (the last is for named templates). Recursion is one of the most effective way of processing tree structures, since such structures typically have arbitrary depth, making it difficult to handle the code within a single function. The generalized identity pattern, discussed later in this section, provides the most generalized form of recursion, copying everything it encounters as it walks down the XML tree unless a specific template redirects it.
  • Stateless - Pattern matching languages, such as XSLT or Regular Expressions, work with instances of information ("states") by transforming one state to another. The advantage to this from a pattern-matching standpoint is that you do not need to worry about the state changing from the beginning of the transformation to the end. Pattern-matching algorithms are much more difficult to implement in a stateful environment, because changes made at one level in an event driven environment may render the section that the XSLT parser is working on irrelevant. However, it should be noted that XSLT also includes mechanisms (xsl:variable and xsl:param) that let the XSLT parser maintain partial state within a transformation. This becomes critical for situations where the XSLT generates XML content for consumption by other parts of the XSLT transformation.
  • Parametric - Most patterns are highly sensitive to initial conditions. Both named and matching templates can include parameters that can change the way a template produces output, and you can use external parameters that can be set through the DOM to control the overall characteristics of the transformation – large scale patterns that modify smaller, more localized templates.
  • Modular - XSLT is as dependent upon good programming practices as any other programming language. One of these practices is to modularize your code as much as possible, to break down discrete programming actions (or sub-transformations, in this case) into separate units. By employing specialized stylesheets that serve as object libraries, you can create a framework of commonly used transformations that can be imported only when needed, making it easier to manage the code and separate simpler actions, such as web page generation, from more complex ones such as component design or schema transformation.


Designing Template Rules

This section covers the following:

  • Identity Patterns: Using <xsl:copy> to Copy Nodes
  • Excluding Elements by Using an Empty <xsl:template>
  • Replacing Elements Using a String Literal instead of <xsl:value-of>
  • Reconnecting a Tree by Using a Pass-through Filter
  • Sorting with an Identity Transformation and Pass-through Filter
  • Using the Identity Transformation


Using the Identity Transformation

The identity filter can be found at the foundation of a wide number of useful transformations. In general, they work best in situations where you're dealing with changes to existing XML data structures that largely preserve the content of those structures – XHTML pages, data set filtering, reordering of records, and so forth. The principal problem with the identity transformation is the flipside of this, forcing a significant amount of accidental coding when dealing with more comprehensive transformations such as ones that map from one schema to another. However, for a significant number of cases, the identity transformation can make the building of code libraries much more effective, helping you separate development between the web designer and the application developer. The identity transformation is useful for the following situations.

XHTML Server

You can use XSLT to catch specific custom elements (such as those in a distinct namespace) and replace the content with some other representation. This lets you create your own custom library of replacement routines. For more information and examples, see Replacing Elements Using a String Literal instead of <xsl:value-of> and Reconnecting a Tree by Using a Pass-through Filter.

Linking and Embedded XHTML

You can use the identity filter to display additional XHTML that may be a part of some other content. For example, you can write a very simple Xlink transformation that will let you expand XML in foreign URLs to content within the document. For more information and examples, see Linking Patterns: Reading XML Files Using document().

Paging

You can create a subset of a document by using the sorting and filtering techniques to retrieve a "page" of output. See Dividing Sort Items into Pages by Using Variables.


Identity Patterns: Using <xsl:copy> to Copy Nodes

The identity pattern makes use of the recursive nature of XSLT by locating the starting point in the XML source tree then applying a generic template to that node to copy all of its children. The children in turn call the same method to make copies of their children and so forth, as shown in the example XSLT file below.

Example

These two template rules together produce an output stream that is identical to the input stream. While the identity pattern by itself seems less than useful, when used in conjunction with other templates to filter, replace, or sort the identity pattern becomes highly critical, as it lets users generate output without needing to know the exact structure of the input.

XML File (books.xml)

Use the Sample XML File (books.xml). Below the line <?xml version='1.0'?>, add the following line:

<?xml-stylesheet type="text/xsl" href="identity.xsl"?>

XSLT File (identity.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <xsl:apply-templates select="*"/>
</xsl:template>

<xsl:template match="*|@*|text()">
    <xsl:copy>
        <xsl:apply-templates select="*|@*|text()"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Formatted Output

A portion of the formatted output is shown here.

Gambardella, MatthewComputer44.952000-10-011998 2000An in-depth look at creating applications with XML.Ralls, KimFantasy5.952000-12-162000A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.Corets, EvaFantasy5.952000-11-171993 1996 2000

Processor Output

A portion of the output stream is shown here.

<?xml version="1.0" encoding="UTF-16"?><catalog><book id="bk101"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre><price>44.95</price><publish_date>2000-10-01</publish_date><release_years>1998 2000</release_years><description>An in-depth look at creating applications with
 XML.</description></book><book id="bk102">...</book></catalog>


Excluding Elements by Using an Empty <xsl:template>

A new template that is contained after the set of identity templates processes the specified nodes differently than just copying the nodes. For example, when applied to books.xml, the following example XSL file produces a new file in which every book except for those in the Fantasy genre are included. This is a classic exclusion filter – a specific element is simply not introduced into the output.

Example

Every book is included in the output except for those in the Fantasy genre.

XML File (books.xml)

Use the Sample XML File (books.xml). Below the line <?xml version='1.0'?>, add the following line:

<?xml-stylesheet type="text/xsl" href="exclusion.xsl"?>

XSLT File (exclusion.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <xsl:apply-templates select="*"/>
</xsl:template>

<xsl:template match="*|@*|text()">
   <xsl:copy>
      <xsl:apply-templates select="*|@*|text()"/>
   </xsl:copy>
</xsl:template>

<xsl:template match="book[genre='Fantasy']"/>

</xsl:stylesheet>

Formatted Output

A portion of the formatted output is shown here. The output lacks the fantasy books.

Gambardella, MatthewComputer44.952000-10-011998 2000An in-depth look at creating applications with XML.Randall, CynthiaRomance4.952000-09-02When Carla meets Paul at an ornithology conference, tempers fly as feathers get ruffled.Thurman, PaulaRomance4.952000-11-021998 1999 2000A deep sea diver finds true love twenty thousand leagues beneath the sea.Knorr, StefanHorror4.952000-12-062000An anthology of horror stories about roaches, centipedes, scorpions and other insects.Kress, PeterScience Fiction6.952000-11-

Processor Output

A portion of the output stream is shown here. The output lacks the fantasy books.

<?xml version="1.0" encoding="UTF-16"?><catalog><book id="bk101"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre><price>44.95</price><publish_date>2000-10-01</publish_date><release_years>1998 2000</release_years><description>An in-depth look at creating applications with
 XML.</description></book><book id="bk106">...</book></catalog>


Replacing Elements Using a String Literal instead of <xsl:value-of>

In a replacement filter, the template given after the identity filters replaces the given node with the contents of the template. For instance, replacement.xsl in Example 1 below changes the genre of any Fantasy book to a Science-Fiction/Fantasy book.

You can create very sophisticated XSLT replacement scripts to do such things as create menus and dynamic tables, incorporate specific blocks of client side script, add boilerplate content and even create far more sophisticated client components using just the replace pattern.

You can use replacement filters to convert custom tags within XML-compliant HTML into output on the server. The file copyright.xml in Example 2 below is an XHTML document that contains a <copyright/> tag . In this particular case, you want the contents of the HTML document to pass through directly, but want to process the copyright element so that it replaces the element with boilerplate code. Note that you can parameterize such elements through attributes or internal text contents.

Example 1

This example changes the genre of any Fantasy book to a Science-Fiction/Fantasy book.

XML File (books.xml)

Use the Sample XML File (books.xml). Below the line <?xml version='1.0'?>, add the following line:

<?xml-stylesheet type="text/xsl" href="replacement.xsl"?>

XSLT File (replacement.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <xsl:apply-templates select="*"/>
</xsl:template>

<xsl:template match="*|@*|text()">
    <xsl:copy>
        <xsl:apply-templates select="*|@*|text()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="book[genre='Fantasy']" >
    <book id="{@id}">
        <title><xsl:value-of select="title"/></title>
        <author><xsl:value-of select="author"/></author>
        <genre>Science-Fiction/Fantasy</genre>
        <price><xsl:value-of select="price"/></price>
        <publish_date><xsl:value-of select="publish_date"/></publish_date>
        <description><xsl:value-of select="description"/></description>
    </book>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Bold added for clarity.

Gambardella, MatthewComputer44.952000-10-011998 2000An in-depth look at creating applications with XML.Ralls, KimScience-Fiction/Fantasy5.952000-12-16A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.Corets, EvaScience-Fiction/Fantasy5.952000-11-17After the collapse of a nanotechnology society in England, the young survivors lay the foundation for a new society.Corets, EvaScience-Fiction/Fantasy5.952001-03-10...

Processor Output

A portion of the output stream is shown here. Four books are listed with <genre>Science-Fiction/Fantasy</genre>.

<?xml version="1.0" encoding="UTF-16"?><catalog><book id="bk101"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre><price>44.95</price><publish_date>2000-10-01</publish_date><release_years>1998 2000</release_years><description>An in-depth look at creating applications with
 XML.</description></book><book id="bk102"><title>Midnight Rain</title><author>Ralls, Kim</author><genre>Science-Fiction/Fantasy</genre><price>5.95</price><publish_date>2000-12-16</publish_date><description>A former architect battles corporate zombies,
 an evil sorceress, and her own childhood to become ...</description></book></catalog>

Example 2

You can use replacement filters to convert custom tags within XML-compliant HTML into output on the server. The file copyright.xhtml is an XHTML document that contains a <copyright/> tag . The contents of the HTML document pass through directly, but the copyright element is replaced by boilerplate code.

To view this example, view the XHTML file in Internet Explorer.

XML File (copyright.xhtml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="copyright.replacement.xsl"?>
<html>
    <head>
     <title>Copyright</title>
  </head>
  <body>
      <h1>A Headline</h1>
      <div>This contains the contents of this story</div>
      <copyright year="2000" />
  </body>
</html>

XSLT File (copyright.replacement.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <xsl:apply-templates select="*"/>
</xsl:template>

<xsl:template match="*|@*|text()">
    <xsl:copy>
        <xsl:apply-templates select="*|@*|text()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="copyright" >
   <div>&#169;<xsl:value-of select="@year"/> Microsoft Corp. All rights Reserved.</div>
</xsl:template>

</xsl:stylesheet>

Formatted Output

A Headline

This contains the contents of this story

©2000 Microsoft Corp. All rights Reserved.

Processor Output

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-16">
<title>Copyright</title>
</head>
<body>
<h1>A Headline</h1>
<div>This contains the contents of this story</div>
<div>©2000 Microsoft Corp. All rights Reserved.</div>
</body>
</html>


Reconnecting a Tree by Using a Pass-through Filter

In a pass-through filter, the node is transformed, but then the children of that node are called recursively to be matched by either some other element or the identity node. This can be useful when you replace an element but you want the children of that element to process independently. For example, an XHTML document may contain a custom tag that places the contents of the element into a floating sidebar element (in IE4.0 and above) using CSS. The source XML document for this transformation would include mechanisms for handling the conversion of specific elements (such as <sb1> for a sidebar first head, or an <sb2> for a sidebar subhead):

Note that the sb1 and sidebar elements both pass their internal contents, which are then mapped by the identity templates to the corresponding HTML. The one caveat when working with replacement or pass-through patterns is that you must have some XSL template ready to catch any element that isn't specifically within the HTML or similar schema.

Example

To view this example, view the XHTML file in Internet Explorer.

XHTML File (sidebars.xhtml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="sidebars.xsl"?>
<html>
<head>
    <title>Sidebar</title>
</head>

<body>
    <h1>About Sidebars</h1>
    <sidebar>
        <sb1>Sidebars on the Web</sb1>
        <p>In a web <b>sidebar</b>, the content is typically floated to the left or right of the main content by using the float CSS property.</p>
    </sidebar>
    <p>A sidebar can be thought of as an adjunct to the main body of text, something that explains a concept or idea that is relevent to the main topic but not necessarily something that works well as part of the text itself.  Sidebars gained the name because they floated to one side of the page. You can use sidebars to produce navigational elements as well as adjacent ideas.</p>
</body>
</html>

XSLT File (sidebars.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <xsl:apply-templates select="*"/>
</xsl:template>

<xsl:template match="*|@*|text()">
    <xsl:copy>
        <xsl:apply-templates select="*|@*|text()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="sidebar" >
    <div style="position:relative;float:left;width:200px;
                background-color:navy;color:white;padding:5px;">
           <xsl:apply-templates select="*|@*|text()"/>
    </div>
</xsl:template>

<xsl:template match="sb1">
    <h2 style="font-family:Verdana"><xsl:value-of select="*|@*|text()"/></h2>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-16">
<title>Sidebar</title>
</head>
<body>
<h1>About Sidebars</h1>
<div style="position:relative;float:left;width:200px;
                background-color:navy;color:white;padding:5px;">
<h2 style="font-family:Verdana">Sidebars on the Web</h2>
<p>In a web <b>sidebar</b>, the content is typically floated to the left or right of the main content by using the float CSS property.</p>
</div>
<p>A sidebar can be thought of as an adjunct to the main body of text, something that explains a concept or idea that is relevent to the main topic but not necessarily something that works well as part of the text itself.  Sidebars gained the name because they floated to one side of the page. You can use sidebars to produce navigational elements as well as adjacent ideas.</p>
</body>
</html>


Sorting with an Identity Transformation and Pass-through Filter

The identity transformation and the pass-through filter can work very well with sorting in XSLT, since you can apply a sort on a set of items through an apply-templates and still be assured of having the contents pass-through to be processed by other applications.

Example

This example orders the books in books.xml by date in descending order, but only for the Fantasy genre.

XML File (books.xml)

Use the Sample XML File (books.xml). Below the line <?xml version='1.0'?>, add the following line:

<?xml-stylesheet type="text/xsl" href="booksort.xsl"?>

XSLT File (booksort.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/">
   <xmp>
      <xsl:apply-templates select="*"/>
   </xmp>
</xsl:template>

<xsl:template match="*|@*|text()">
    <xsl:copy><xsl:apply-templates select="*|@*|text()"/></xsl:copy>
</xsl:template>

<xsl:template match="catalog">
    <xsl:apply-templates select="book[genre='Fantasy']">
        <xsl:sort select="publish_date" order="descending"/>
    </xsl:apply-templates>
</xsl:template>

</xsl:stylesheet>

Processor Output

A portion of the output stream is shown here.

<?xml version="1.0" encoding="UTF-16"?>
<xmp xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<book id="bk105"><author>Corets, Eva</author>
<title>The Sundered Grail</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2001-09-10</publish_date>
<release_years>2000</release_years>
<description>The two daughters of Maeve, half-sisters, battle
one another for control of England. Sequel to Oberon's
Legacy.</description>
</book>
<book id="bk104"><author>Corets, Eva</author>
<title>Oberon's Legacy...</book></xmp>


Design Patterns for Using Variables and Parameters

Variable patterns take advantage of some of the newest features of XSLT, the ability to create variables and pass parameters to retain temporary information. Variables can provide a way of creating XML structures on the fly, can simplify coding and can be used to manipulate strings and other data types. Parameters on the other hand create ways of passing information into a template or even a style sheet, and as such are critical in the development of larger system solutions.

This section covers the following:

  • Design Patterns for Using Parameters
  • Converting Node-sets by Using Variables
  • Dividing Sort Items into Pages by Using Variables


Design Patterns for Using Parameters

Parameters are one of the most useful new features to XSLT, and they can be leveraged in a number of different ways to make your style sheets more powerful:

Defaults for Parameters

If you include a select element with a parameter, the parameter will always bind to the value (or nodeset) defined by the select if not explicitly changed through an external process. For example, the following parameter expression sets the value of the $clock.type parameter to the strong "long_time" if the parameter is not otherwise set from an external call:

<xsl:template name="clock">
    <xsl:param name="clock.type" select=" 'long_time' "/>
    <!-- clock code -->
</xsl:template>

If the named template is called with a different clock-type, then the new type overrides the default one:

<xsl:call-template name="clock">
      <xsl:with-param name="clock.type" select=" 'short_time' "/>
</xsl:call-template>

On the other hand, if no parameter is explicitly called with the <xsl:with-param> command, then the default value of 'long_time' is used instead:

<xsl:call-template name="clock"/>

Passing Strings into a Variable or Parameter

To pass a string into a variable or parameter, the string itself must be quoted independently of the attribute quotes, otherwise the string will be interpreted as an XPath Expression. In the example above, the expression select=" 'long_time' " is interpreted as assigning the string value "long_time" to the clock.type parameter. Note that numeric expressions don't need to be quoted in this way, but dates do (otherwise "2000-10-15" will be interpreted as the number 1975, rather than as October 15, 2000).

XPath Expressions for Variables or Parameters

A variable or parameter with a select attribute set to an Xpath expression will be assigned the node-set that satisfies the XPath expression, relative to the current context. This last point is important – a variable shares the same context as the template that it's called from, with variables or parameters defined as children of the <xsl:stylesheet> element being considered to have match the root context. Thus,

<xsl:variable name="books" select="book"/>

applied against books.xml will only retrieve a node-set if the variable is defined within the catalog matching template. For example, the following will retrieve the number of books in the catalog:

Example

XML File (books.xml)

Use the Sample XML File (books.xml). Below the line <?xml version='1.0'?>, add the following line:

<?xml-stylesheet type="text/xsl" href="count.xsl"?>

XSLT File (count.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <xsl:apply-templates select="catalog"/>
</xsl:template>

<xsl:template match="catalog">
    <xsl:variable name="books" select="book"/>
   Number of books: <xsl:value-of select="count($books)"/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Number of books: 12

Processor Output

<?xml version="1.0" encoding="UTF-16"?>
   Number of books: 12


Converting Node-sets by Using Variables

According to the XSLT specification, the template content within a variable is called an XML Fragment. If variables are passed as output, the content will be displayed as XML, but internally it is treated as String, not a node-set. To compensate for this, a number of XSLT parsers, including the MSXML3 parser, has a node-set function that converts such created strings back into node-sets. Node-set() is a powerful tool, because you can use XSLT to generate XML content dynamically as a string then convert that string back into a set of nodes for later processing.

Declaring msxsl: namespace before using node-set()

The msxsl namespace must be declared beforehand before node-set() can be used. This namespace contains the definitions for node-set() and a number of other MSXML related functions (as well as the msxsl:script element), and should be declared as:

<xsl:stylesheet xmlns:msxsl="urn:schemas-microsoft-com/xslt" version="1.0"/>

The xmlns:msxsl part indicates that you're defining a custom namespace prefix, while urn:schemas-microsoft-com/xslt points to a virtual namespace marker that uniquely identifies the functionality of that particular set of expressions.

Example

The date.xsl style sheet converts any <date>2000-11-01</date> tags that it encounters (with different dates) with the long version of that date ("November 1, 2000", for example).

XML File (date.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="date.xsl"?>
<html>
<head>
   <title>Date</title>
</head>

<body>
   <date>2000-12-10</date>
</body>
</html>

XSLT File (date.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">

<xsl:param name="date" select="2000-10-15"/>
<xsl:template match="/">
   <xsl:apply-templates select="*"/>
</xsl:template>

<xsl:template match="*|@*|text()">
   <xsl:copy><xsl:apply-templates select="*|@*|text()"/></xsl:copy>
</xsl:template>

<xsl:template match="date">
   <xsl:call-template name="date.convert">
      <xsl:with-param name="date" select="."/>
   </xsl:call-template>
</xsl:template>

<xsl:template name="date.convert">
   <xsl:param name="date" select="'2000-01-04'"/>
   <xsl:variable name="months.1">
      <month>January</month>
      <month>February</month>
      <month>March</month>
      <month>April</month>
      <month>May</month>
      <month>June</month>
      <month>July</month>
      <month>August</month>
      <month>September</month>
      <month>October</month>
      <month>November</month>
      <month>December</month>
   </xsl:variable>
   <xsl:variable name="months" select="msxsl:node-set($months.1)"/>
   <xsl:value-of select="concat($months/*[number(substring($date,6,2))],
      ' ',number(substring($date,9,2)),',     ',substring($date,1,4))"/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

December 10, 2000

Processor Output

<html><head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-16">
<title>Date</title>
</head>
<body>December 10,     2000</body>
</html>


Dividing Sort Items into Pages by Using Variables

Paging is the dual process of sorting a set of data by a certain criterion, then extracting from the set a "page" of a specific number of items. This resulting node-set can in turn be manipulated to produce a displayed page. In XSLT, paging requires using variables to hold the intermediate sorted items.

Make the Sorting Mechanism an Import

While the routines for doing filtered sorts in XSLT can be somewhat cumbersome, they are also quite generic. As such it may be advantageous to place these routines within a different XSLT document as a general set of library routines, then import the stylesheet when needed.

Paging is a very common operation in web applications, so common that it should be made into an imported stylesheet. The paging.xsl stylesheet in the following example demonstrates how this can be accomplished, as well as how it can be tied into the documentation.xsl stylesheet to display a set of options on a page.

Because of its complexity, the transformation also includes a documentation namespace that describes how the template works.

Example

To view this example, view paging.xsl in Internet Explorer.

Auxiliary XSLT File (documentation.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
      xmlns:doc="urn:schemas-vbxml-com:document">
<xsl:output method="xml"/>

<xsl:template match="/">
    <html>
        <body>
            <xsl:apply-templates select="//doc:summary"/>
            <xsl:apply-templates select="//xsl:template[@name]"/>
            <xsl:apply-templates select="//doc:example"/>
        </body>
    </html>
</xsl:template>

<xsl:template match="doc:summary">
    <h1><xsl:value-of select="doc:title"/></h1>
    <div><xsl:value-of select="doc:description"/></div>
</xsl:template>

<xsl:template match="xsl:template[@name]">
    <h2>Named Template: <xsl:value-of select="@name"/></h2>
    <div><xsl:value-of select="@doc:description"/></div>
    <h3>Parameters</h3>
    <ul>
    <xsl:for-each select="xsl:param[not(@doc:private='yes')]">
        <li><b><xsl:value-of select="@name"/>. </b> <xsl:value-of select="@doc:description"/>
        <xsl:if test="@select">
        <i>[default=<xsl:value-of select="@select"/>]</i>
        </xsl:if>
        </li>
    </xsl:for-each>
    </ul>
</xsl:template>

<xsl:template match="doc:example">
    <h3>Example</h3>
    <xmp>
        <xsl:value-of select="*|@*|text()" disable-output-escaping="yes"/>
    </xmp>
</xsl:template>

</xsl:stylesheet>

XSLT File (paging.xsl)

<?xml-stylesheet type="text/xsl" href="documentation.xsl"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:doc="urn:schemas-vbxml-com:document"
    version="1.0">
    <xsl:output method="xml" indent="yes"/>

<xsl:template name="page.filter" doc:description="Sorts a dataset, the provides a paged subset containing page.size entries.">
    <xsl:param name="dataset" doc:description="Contains an XPath dataset expression"/>
    <xsl:param name="page" select="1" doc:description="Contains the specific page of the data (1 based)"/>
    <xsl:param name="page.size" select="10" doc:description="Contains the number of items per page"/>
    <xsl:param name="sort.filter" select="name(*[position()=1])" doc:description="The name of the descendant element or attribute that orders the sort."/>
    <xsl:param name="sort.order" select="'ascending'"  doc:description="The order of the sort, either 'ascending' or 'descending'"/>

    <xsl:variable name="dataset.sorted.1">
        <xsl:choose>
        <xsl:when test="$sort.order='descending'">
        <xsl:for-each select="$dataset">
            <xsl:sort select="descendant::*[name(.)=$sort.filter]|@*[name(.)=$sort.filter]" order="descending"/>
            <xsl:copy-of select="."/>
        </xsl:for-each>
        </xsl:when>
        <xsl:otherwise>
        <xsl:for-each select="$dataset">
            <xsl:sort select="descendant::*[name(.)=$sort.filter]|@*[name(.)=$sort.filter]" order="ascending"/>
            <xsl:copy-of select="."/>
        </xsl:for-each>
        </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

    <xsl:variable name="dataset.sorted" select="msxsl:node-set($dataset.sorted.1)"/>
    <xsl:for-each select="$dataset.sorted/*[(position() &gt; ($page - 1) * $page.size) and (position() &lt;= ($page) * $page.size)]">
        <xsl:copy-of select="."/>
    </xsl:for-each>
</xsl:template>

<xsl:template name="page.filter.strip">
    <xsl:param name="dataset" doc:description="Contains an XPath dataset expression"/>
    <xsl:param name="sort.filter" doc:description="The name of the descendant element or attribute that orders the sort."/>
    <xsl:param name="sort.order" doc:description="The order of the sort, either 'ascending' or 'descending'"/>
    <xsl:param name="page" doc:description="Contains the specific page of the data (1 based)"/>
    <xsl:param name="page.indexed" select="1" doc:private="yes"/>
    <xsl:param name="page.size" doc:description="Contains the number of items per page"/>
    <xsl:param name="url.base" doc:description="The base URL that contains the CGI for displaying the content."/>

    <td>
    <xsl:choose>
        <xsl:when test="$page.indexed=$page">
            <xsl:value-of select="$page.indexed"/>
        </xsl:when>
        <xsl:otherwise>
            <a href="{$url.base}page={$page.indexed}&amp;page.size={$page.size}&amp;sort.order={$sort.order}&amp;sort.filter={$sort.filter}&amp;">
            <xsl:value-of select="$page.indexed"/>
            </a>
        </xsl:otherwise>
    </xsl:choose>
    </td>

    <xsl:if test="$page.indexed &lt; ceiling(count($dataset) div $page.size)">
        <xsl:call-template name="page.filter.strip">
            <xsl:with-param name="dataset" select="$dataset"/>
            <xsl:with-param name="sort.filter" select="$sort.filter"/>
            <xsl:with-param name="sort.order" select="$sort.order"/>
            <xsl:with-param name="page" select="$page"/>
            <xsl:with-param name="page.size" select="$page.size"/>
            <xsl:with-param name="url.base" select="'xpipes.asp?source=book_catalog&amp;xform=Paging.Example&amp;'"/>
            <xsl:with-param name="page.indexed" select="$page.indexed + 1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

<doc:summary>
    <doc:title>Page Filter Stylesheet</doc:title>
    <doc:description>The page.filter named template is useful for creating paged output based upon a specific sort criterion. It takes the unsorted node-set as an argument, along with the specific page, page size, sort order and sort filter to generate an element the children of which are the specific paged output. </doc:description>
</doc:summary>

<doc:example><![CDATA[
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    version="1.0">

<xsl:import href="paging.xsl"/>
<xsl:template match="/">
    <html>
        <body>
        <xsl:variable name="sorted.items">
            <xsl:call-template name="page.filter">
                <xsl:with-param name="dataset" select="//book"/>
                <xsl:with-param name="sort.filter" select="'title'"/>
                <xsl:with-param name="sort.order" select="'ascending'"/>
                <xsl:with-param name="page" select="2"/>
                <xsl:with-param name="page.size" select="5"/>
            </xsl:call-template>
        </xsl:variable>
        <table border="1">
        <xsl:for-each select="msxsl:node-set($sorted.items)/*">
            <tr>
                <td><xsl:value-of select="title"/></td>
                <td><xsl:value-of select="author"/></td>
                <td><xsl:value-of select="publish_date"/></td>
            </tr>
        </xsl:for-each>
        </table>
        </body>
    </html>
</xsl:template>
</xsl:stylesheet>
]]>    </doc:example>

</xsl:stylesheet>

Formatted Output

A portion of the formatted output is shown here.

See Also

Using XSLT Keys to Group Data


Class Patterns: Using <xsl:import> and <xsl:include>

The distinction between included and imported templates is subtle but important, and misuse can be difficult to debug.

This section also covers the following:

  • Developing a Library of XSLT Templates

An include Loads XSLT Documents Directly

<xsl:include> passes the text contents directly into the calling XSLT body. If a method, variable, or parameter collides, the XSL parser will produce an error and not compile. Include is better for including extensions, although it is faster than xsl:import.

An import Loads Templates, Parameters or Variables Only If Not Already Defined

<xsl:import> will load a template or parameter only if the calling document doesn't already have the same element. Imports are safer, but they take a marginally longer time to compile.

An include or import Cannot Be Parameterized Directly

You can't assign a variable to the href attribute of either <xsl:import> or <xsl:include>. However, you could use XSLT to generate the appropriate includes or imports in a second XSLT document.

In general, imported stylesheets are preferable if there is any chance of namespace conflict – an identically named or matched template, a global variable or parameter, and so on, while includes work best in situations where you're including boilerplate information that is likely to be unique (system variables that may have application across several stylesheets.

Benefits of Imported Templates

XSLT stylesheets can be used either to provide general matching templates or to include named templates that perform more specific services. While each type of document has advantages and disadvantages, named templates work more easily as "library" functions. There are a number of benefits to splitting up templates and parameters in subordinate stylesheets.

Encapsulation

XSLT doesn't have encapsulation per se, though you can introduce some organization through the underlying structure and schema. Within XSLT in particular, you can introduce encapsulation of named templates, variable and parameters by moving such named templates into dedicated "object" libraries -- for example, a stylesheet that contained a number of templates, both named and matched, for generating a certain type of table.

See Also

Importing and Including Style Sheets


Developing a Library of XSLT Templates

By placing XSLT resources into separate files, you can start developing a library of useful transformations to do such things as create tables, form objects, banners, menus, and treeview controls.There are a few simple organizational techniques that can help make template libraries easier to manage.

Stylesheets Should Reflect the Object Names and Should Echo That Name In the First Named Template

A good rule of thumb when developing libraries is to name the XSLT stylesheet with the name of the object that you're defining, then create a single template with that same name that acts as the point of entry for the stylesheet.

Avoid Root Matches

Avoid using root matches "/" in these library routines, as these will either conflict or be overwritten by the root matches of the calling function.

Use the Mode Attribute Extensively and Avoid Unmoded Matches

Namespace collisions tend to become a problem when dealing with template matches (especially with wildcard matches). You can employ the mode attribute within template matches and apply-templates calls to tie the template to the specific name of the XSLT file.

Example

The xmlcode.xsl file in this example is designed for use with an identity transformation (see Identity Patterns: Using <xsl:copy> to Copy Nodes). It displays the contents of any XML contained within an <xmlcode> node as an XML tree, and is useful for displaying XML code in web pages in the treeview format familiar to IE5 users.

Because it cannot be known ahead of time what elements or attributes will be contained in the code, the wildcard character is employed instead. However, to keep this from matching any other character in the transformation, you would either need to include for each match the explicit XPath qualification "ancestor::xmlcode//*" which is likely to make for inefficient code, or you need to specify that the wildcard matches only when called as part of the xmlcode mode, as the named template "showXML" does when it calls the root element that starts the display:

<xsl:apply-templates select="$xml_root" mode="xmlcode"/>

XML File (booksshort2.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="xmlcode.xsl"?>
<xmlcode>
   <catalog>
      <book id="bk101">
         <author>Gambardella, Matthew</author>
         <title>XML Developer's Guide</title>
         <genre>Computer</genre>
         <price>44.95</price>
         <publish_date>2000-10-01</publish_date>
         <description>An in-depth look at creating applications with
    XML.</description>
      </book>
      <book id="bk102">
         <author>Ralls, Kim</author>
         <title>Midnight Rain</title>
         <genre>Fantasy</genre>
         <price>5.95</price>
         <publish_date>2000-12-16</publish_date>
         <description>A former architect battles corporate zombies,
    an evil sorceress, and her own childhood to become queen of the
    world.</description>
      </book>
      <book id="bk103">
         <author>Corets, Eva</author>
         <title>Maeve Ascendant</title>
         <genre>Fantasy</genre>
         <price>5.95</price>
         <publish_date>2000-11-17</publish_date>
         <description>After the collapse of a nanotechnology society
    in England, the young survivors lay the foundation for a new
   society.</description>
      </book>
   </catalog>
</xmlcode>

XSLT File (identity.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <xsl:apply-templates select="*"/>
</xsl:template>

<xsl:template match="*|@*|text()">
    <xsl:copy>
        <xsl:apply-templates select="*|@*|text()"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

XSLT File (xmlcode.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
      xmlns:state="http://www.vbxml.com/state">

<xsl:template match="xmlcode">
    <xsl:choose>
        <xsl:when test="@src">
            <xsl:call-template name="showXML">
                <xsl:with-param name="xml_root" select="document(@src)/*"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:choose>
                <xsl:when test="*">
                    <xsl:call-template name="showXML">
                        <xsl:with-param name="xml_root" select="*"/>
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <pre><xsl:value-of select="." disable-output-escaping="no"/></pre>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="*" mode="xmlcode">
<ul class="xmlcode">
    <li class="xmlcode">
        <span class="bracket">&lt;</span>
        <span class="element_name"><xsl:value-of select="name(.)"/></span>
        <span class="attribute_list"><xsl:apply-templates select="@*" mode="xmlcode"/></span>
        <span class="bracket">
            <xsl:if test="not(text()|*)">/</xsl:if>&gt;
        </span>
        <xsl:if test="text()|*">
            <xsl:apply-templates select="*|text()|comment()|processing-instruction()" mode="xmlcode"/>
            <span class="bracket">&lt;/</span>
            <span class="element_name"><xsl:value-of select="name(.)"/></span>
            <span class="bracket">&gt;</span>
        </xsl:if>
    </li>
</ul>
</xsl:template>

<xsl:template match="text()" mode="xmlcode">
   <span class="text">
   <xsl:choose>
       <xsl:when test="contains(.,'&#13;')">
           <pre><xsl:value-of select="." disable-output-escaping="no"/></pre>
       </xsl:when>
       <xsl:otherwise>
           <xsl:value-of select="." disable-output-escaping="no"/>
       </xsl:otherwise>
       </xsl:choose>
    </span>
</xsl:template>

<xsl:template match="comment()" mode="xmlcode">
    <div class="comment">&lt;!-- <xsl:value-of select="."/> --&gt;</div>
</xsl:template>

<xsl:template match="@*" mode="xmlcode">
    <xsl:text> </xsl:text>
    <span class="attribute_name"><xsl:value-of select="name(.)"/></span>="
    <span class="attribute_value"><xsl:value-of select="."/></span>"
</xsl:template>

<xsl:template name="showXML">
    <xsl:param name="xml_root"/>
    <xsl:param name="xmlcode_pos" select="1"/>
    <div>
        <style>
            li.xmlcode {list-style-type:none;}
            ul.xmlcode {margin-left:20px;}
            .bracket {color:blue;}
            .element_name {color:brown;}
            .attribute_list {color:blue;}
            .attribute_name {color:red;}
            .attribute_value {color:red;font-weight:bold;}
            .comment {color:#C0C0C0;}
            .text {color:black;font-weight:bold;}
        </style>
        <xsl:apply-templates select="$xml_root" mode="xmlcode"/>
    </div>
</xsl:template>

</xsl:stylesheet>


Linking Patterns: Reading XML Files Using document()

The document() function is one of the most powerful tools within XSL. It effectively lets you work with XML data from any number of different sources without having to use multiple XSLT transformations. It also lets you get information about the XSLT document itself. With document() you can do the following tasks, covered in this section:

  • Processing a List of XML Files Using document()
  • Processing an External Document Using document()
  • Referencing the Current XSLT File when Using document()
  • Extracting URL-Based Data Dynamically Using document()


Processing a List of XML Files Using document()

The document() function can be used to read a "table of contents" from a number of different XML providers and turn them into effectively one large document. The aggregation ability of document() means that you can produce such things as a dynamic "help" book with information that only touches on specific topics, a table pulled from separate XML quarterly reports, or a set of records based upon some initial index sort where the records are in separate documents.

Example

The file blocktoc.xml contains references to three other xml documents. The file multidocs.xsl reads all through references in at the same time as a node-set, retrieves the contents of the files and makes each secondary document a node in a node-set:

To run this example, view blocktoc.xml in Internet Explorer.

XSLT File (multidocs.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml"/>

<xsl:template match="/">
   <html>
   <head>
      <title>MultiDocs</title>
   </head>
   <body>
      <xsl:copy-of select="document(//document/@href)"/>
   </body>
   </html>
</xsl:template>

</xsl:stylesheet>

XML File 1 (blocktoc.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="multidocs.xsl"?>
<documents>
    <document href="blockred.xml"/>
    <document href="blockgreen.xml"/>
    <document href="blockblue.xml"/>
</documents>

XML File 2 (blockblue.xml)

<?xml version='1.0'?>
<div style="background-color:blue;width:300px;height:100px;color:white">
<h3>Blue Background</h3>
<p>This contains a <b>blue</b> background with <b>white</b> text, and
also shows that you can pass subordinate XML tags in through this mechanism.</p>
</div>

XML File 3 (blockgreen.xml)

<?xml version='1.0'?>
<div style="background-color:green;width:300px;height:100px;color:white">
<img src="xsltshapes.gif" align="left"/>An image which is incorporated into the
output. Note that document retains the location of the source directory.
</div>

XML File 4 (blockred.xml)

<?xml version='1.0'?>
<div style="background-color:red;width:300px;height:100px;color:yellow">
Stylistically you can do a lot with CSS, as this demonstrates.
</div>

Graphic File (xsltshapes.gif)

To copy this graphic to your drive, right-click the graphic and then click Copy. Click Start, Programs, Accessories, Paint. Drag the lower right handle of the white working area up to the upper left to make the white area small (1/2 inch). Then press CTRL+V to paste the graphic, and save as xsltshapes.gif.

Formatted Output

Processor Output

<?xml version="1.0" encoding="UTF-16"?><html xmlns:msxsl="urn:schemas-microsoft-com:xslt"><head><title>MultiDocs</title></head><body><div style="background-color:red;width:300px;height:100px;color:yellow">
Stylistically you can do a lot with CSS, as this demonstrates.
</div>
<div style="background-color:green;width:300px;height:100px;color:white">
<img src="xsltshapes.gif" align="left" />An image which is incorporated into the
output. Note that document retains the location of the source directory.
</div>
<div style="background-color:blue;width:300px;height:100px;color:white">
<h3>Blue Background</h3>
<p>This contains a <b>blue</b> background with <b>white</b> text, and
also shows that you can pass subordinate XML tags in through this mechanism.</p>
</div>
</body></html>


Processing an External Document Using document()

The results of a document() query is a nodeset that is effectively identical to internal nodesets. As a consequence, you can read a document() and use it as one element in an XPath expression - for example, the XPath expression

   document('books.xml')//book[@genre='Fantasy']

will pull from the books.xml file all Fantasy books.

See Also

Sample XML File (books.xml)


Referencing the Current XSLT File when Using document()

You can use a document shortcut to retrieve a reference to the current stylesheet document. For example, parameters.show.xsl in the example below uses the XPath expression

   document('',*)//xsl:param

to reference the XSLT document itself and retrieve all of the parameters. Note that the document retrieved is the XSLT document that generated the XSLT instance, not the instance itself; as a consequence, if you programmatically set a parameter in memory, this change will not be reflected in the node-sets retrieved.

The main advantage of being able to query the current XSLT document is in generating documentation. For example, in parameters.show.xsl, the routine can query either the current stylesheet or some other stylesheet and read the global parameters, which would be the first step in generating a library of XSLT stylesheet resources. You can also do the same with imported and included stylesheets (see below), by reading the href attribute of either of these, loading them into a second document, then performing the same transformations.

Example

To run this example, view the XSLT file in Internet Explorer.

XML File

None; the XSLT file calls itself.

XSLT File (parameters.show.xsl)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="parameters.show.xsl"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">

<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="stylesheet" select="''"/>
<xsl:param name="a" select="3"/>
<xsl:param name="b" select="4"/>

<xsl:template match="/">
   <xsl:variable name="stylesheetName">
      <xsl:choose>
           <xsl:when test="$stylesheet = ''">
               current stylesheet
           </xsl:when>
           <xsl:otherwise>
               '<xsl:value-of select="$stylesheet"/>'
           </xsl:otherwise>
       </xsl:choose>
   </xsl:variable>

   <h3>Local parameters for <xsl:value-of select="$stylesheetName"/></h3>

   <xsl:for-each select="document($stylesheet,*)//xsl:stylesheet/xsl:param">
       Parameter: <xsl:value-of select="@name"/> = <xsl:value-of select="@select"/><br/>
   </xsl:for-each>

   <xsl:for-each select="document($stylesheet,*)//xsl:import/@href">
       <xsl:variable name="importedDocURL" select="."/>
       <h3>Imported parameters for <xsl:value-of select="$stylesheetName"/>, Imported File '<xsl:value-of select="$importedDocURL"/>'</h3>
       <xsl:for-each select="document(string($importedDocURL))//xsl:stylesheet/xsl:param">
       Parameter: <xsl:value-of select="@name"/> = <xsl:value-of select="@select"/><br/>
       </xsl:for-each>
   </xsl:for-each>

   <xsl:for-each select="document($stylesheet,*)//xsl:include/@href">
       <xsl:variable name="includedDocURL" select="."/>
       <h3>Included parameters for <xsl:value-of select="$stylesheetName"/>, Imported File '<xsl:value-of select="$includedDocURL"/>'</h3>
       <xsl:for-each select="document(string($includedDocURL))//xsl:stylesheet/xsl:param">
          Parameter: <xsl:value-of select="@name"/> = <xsl:value-of select="@select"/><br/>
       </xsl:for-each>
   </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Local parameters for current stylesheet

Parameter: stylesheet = ''
Parameter: a = 3
Parameter: b = 4

Processor Output

<h3 xmlns:msxsl="urn:schemas-microsoft-com:xslt">Local parameters for
               current stylesheet
           </h3>
       Parameter: stylesheet = ''<br xmlns:msxsl="urn:schemas-microsoft-com:xslt" />
       Parameter: a = 3<br xmlns:msxsl="urn:schemas-microsoft-com:xslt" />
       Parameter: b = 4<br xmlns:msxsl="urn:schemas-microsoft-com:xslt" />


Extracting URL-Based Data Dynamically Using document()

Using a combination of parameters, string methods, and document(), you can create either an XPath or a SQL query against a URL based database system such as SQL Server 2000. This points to the fact that you can develop web services that do not necessarily need a SOAP envelope to work, but instead just require a cogent schema for retrieving parameters from form data.


Design Patterns for Scripting and Extension Functions

You can create scripting extensions. In the XSLT 1.0 Recommendation, there is a provision that lets vendors specify how they wish to extend their XSLT functionality, but it is somewhat ambiguous. This ambiguousness has in turn meant that there are now several similar but not identical extension mechanisms, though XSLT 1.1 may consolidate the standards. The Microsoft MSXML3 parser uses a COM based extension built around either a <msxsl:script> node or by associating a COM object with a namespace in DOM. The scripting mechanism is covered in this section, in the following topics:

  • Declaring the Namespace for Extension Functions
  • Defining the Script Object Using <msxsl:script>
  • Calling Extension Functions by Using Namespace:Funcname()
  • Defining COM Objects within Script Blocks


Declaring the Namespace for Extension Functions

Prior to building the <msxsl:script> tag, two namespaces must be declared. The first is the msxsl: namespace which defines the scripting block functionality, the second is a namespace for the object that you are creating. For example, the following xmlns:re attribute declares an extension for a set of regular expression routines:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
      xmlns:re="urn:schemas-microsoft-com:regex">

The above snippet is from regex.xsl in Defining COM Objects within Script Blocks.


Defining the Script Object Using <msxsl:script>

Functions and variables within the script object become properties and methods within the namespace declaration. In essence, with the namespace you are defining a functional interface. For example, the following function lets you add a regular expression to a temporary set of such expressions, associate with it a regular expression pattern, and the indicate through reSwitch whether the expression should be global ("g"), ignore case ("i"), both ("gi"), or neither ("").

<msxsl:script language="JavaScript" implements-prefix="re"><![CDATA[
        function add(reName,rePattern,reSwitch){
            if (reSwitch==null){
                reSwitch="";
                }
            regexes[reName]=new RegExp(rePattern,reSwitch);
            return "";
            }

The above snippet is from regex.xsl in Defining COM Objects within Script Blocks.


Calling Extension Functions by Using Namespace:Funcname()

The call for an extension defined within the script block is referenced through both its name and its namespace prefix (which is given in the implements-prefix attribute of the msxsl:script element). In the example below, in the add function, the stylesheet getByMonthDate.xsl adds a named expression called 'YrMnthTest' which matches only those books from the books.xml function that have a publish_date in the year 2000.

Example

This example outputs only the data from books that have a publish_date in the year 2000.

XML File (books.xml)

Use the Sample XML File (books.xml). Below the line <?xml version='1.0'?>, add the following line:

<?xml-stylesheet type="text/xsl" href="getByMonthDate.xsl"?>

XSLT File (getByMonthDate.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
      xmlns:re="urn:schemas-microsoft-com:regex">

<xsl:import href="regex.xsl"/>
<xsl:output method="xml"/>
<xsl:param name="year" select="2000"/>
<xsl:param name="month" select="10"/>

<xsl:template match="/">
    <xsl:value-of select="re:add('YrMnthTest',concat($year,'-','[0',$month,'|',$month,']'),'gi')"/>
    <table>
    <xsl:apply-templates select="//book[re:test('YrMnthTest',string(publish_date))]"/>
    </table>
</xsl:template>

<xsl:template match="book">
    <tr>
        <td><xsl:value-of select="title"/></td>
        <td><xsl:value-of select="author"/></td>
        <td><xsl:value-of select="publish_date"/></td>
    </tr>
</xsl:template>

</xsl:stylesheet>

XSLT File with Script Functions (regex.xsl)

Use regex.xsl in Defining COM Objects within Script Blocks.

Formatted Output

Processor Output

<?xml version="1.0" encoding="UTF-16"?><table xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:re="urn:schemas-microsoft-com:regex"><tr><td>XML Developer's Guide</td><td>Gambardella, Matthew</td><td>2000-10-01</td></tr><tr><td>Midnight Rain...</td></tr></table>


Defining COM Objects within Script Blocks

Using the same mechanism as described by the scripting language, you can load a COM object into a variable and then work against this variable. The Scripting interface is one example of this, as it includes both the FileStreamObject and the Regular Expressions engine.

The full code for regex.xsl makes use of the Javascript Regex object, which is defined within the scripting environment.

XSLT File (regex.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
      xmlns:re="urn:schemas-microsoft-com:regex">

<msxsl:script language="JavaScript" implements-prefix="re">
<![CDATA[
   var regexes=new Object;
   function add(reName,rePattern,reSwitch){
       if (reSwitch==null){
           reSwitch="";
           }
       regexes[reName]=new RegExp(rePattern,reSwitch);
       return "";
       }

   function exec(reName,reString,index){
       if (typeof(reString)=='object'){
           reString=reString[0].text;
           }
       var arr=regexes[reName].exec(reString);
       if (arr==null){
           return "";
           }
       else {
           if (index==null){
               return arr.length;
               }
           else {
               if (index >-1 && index<arr.length){
                   return arr[index];
                   }
               else {
                   return "";
                   }
               }
           }
       }

   function test(reName,reString){
       if (typeof(reString)=='object'){
           reString=reString[0].text;
           }
       return regexes[reName].test(reString);
       }

   function compile(reName,rePattern){
       regexes[reName].compile(rePattern);
       return "";
       }

   function split(reName,reString,index){
       if (typeof(reString)=='object'){
           reString=reString[0].text;
           }
       if (index==null){
           return reString.split(regexes[reName]).length;
           }
       else {
           return reString.split(regexes[reName])[index];
           }
       }

]]></msxsl:script>

</xsl:stylesheet>


Using Template Patterns for Common Transformations

This section covers the following:

  • Introduction to Template Patterns
  • Using Design Patterns for Constructing Tables
  • Creating Selection Boxes Using XSLT Templates
  • Operating on Strings Using an XSLT Utility File


Introduction to Template Patterns

Template patterns can be thought of as XSLT components -- collections of multiple template rules that work together to produce specific output, such as tables, hierarchical treeviews, and forms. These patterns, in addition to building useful widgets, often have a number of common characteristics.

  • Primary Named Template - Most template patterns rely on a single primary named template that acts as the entry point for most other templates in that pattern. For utility sake, that template's name should echo the name of they stylesheet, perhaps with ".draw" or ".show" appended to the end to indicate that this should be treated analogously to a method.
  • Secondary Named Templates - These templates are not intended to be called directly from an external XSLT document. Instead, they are more or less the same things as private methods or properties in procedural code.
  • Modal Matching Templates - A modal matching template is one in which a pattern is provided for matching in a generic fashion, but the named template has a mode attribute that locks it in to a named template elsewhere in the XSLT structure. These are especially useful for creating templates that override the default action of this template.
  • Import Oriented - Template patterns are large and complicated enough that they could prove unwieldy in most XSLT transforms. By making such templates import oriented (largely by removing the match to the root node) you can start creating libraries of such widgets.


Using Design Patterns for Constructing Tables

Tables are an integral part of HTML, and XML data in particular is likely to be displayed as tables at some point. Fortunately, table construction is very simple in XSLT even in a generic fashion.

Constructing the Column Headers

The column header row and cells should be generated independently of the actual row generation.. You can use the names of the elements for the columns, use explicitly defined cells within your stylesheet (not generally recommended for generic headers) or use external resources (such as those of an XML schema) to store this information. The example given here looks at the first method -- using element names as cell headers.

Enclosing the Table

The <table> element must be placed outside of the <xsl:apply-templates>, <xsl:call-template> or <xsl:for-each> that defines both the column header row and each of the subsequent row elements. If general, to keep the mechanism as generic as possible, you should use named templates and pass the current row or header cell nodesets as parameters into such templates.Each row in turn should use a similar mechanism for displaying the cells (the individual column elements) of the table.

Sub-classing Cell Templates

It is often useful to create a generic matching template (with a mode attribute) for displaying the content of a given cell. This template will default to displaying the contents in a generic fashion, but you can then write templates with the same mode value set that match specific element names (or other such patterns). In this way you can handle normal text output for a book catalog, yet format dates or numbers differently (as is shown in the example).

Using CSS Classes with Tables

By associating specific CSS classes with your tables, you can control the media presentation of the table dynamically. This can be especially useful in conjunction with scripting, as you can change classes through script to affect visibility, background color, and other attributes.

Scripting a Table

Although it is possible to set events such as onclick or onmouseover on each cell in the table, you may be better off placing one set of event handlers on the <table> element itself then check the corresponding window.event.srcElement object in the handlers to get a handle to the specific element that generated the event.

Example

This example shows how to generically construct a table by using separate XSLT files.

XML File (book_catalog.xml)

Use book_catalog.xml, in Sample XML File for Constructing a Table, and make sure the href attribute references bookcatalogtable.xsl.

XSLT File (bookcatalogtable.xsl)

Use bookcatalogtable.xsl, in Sample XSLT File for Constructing a Table.

This file provides an example of how a basic table can be created that incorporates sub-classing, CSS and scripting. It calls the named template table_basic to generate output. Note that you can override both styles (here, table_basic_row0 style, which controls the color of alternating rows, replaces light green output with light blue output), and scripts (the processClick() function here) by placing the overriding elements after the named-template call.

XSLT File for Date Printing (date.xsl)

Use date.xsl, in Converting Node-sets by Using Variables. This spells out dates in a standard format.

Auxiliary XSLT File (table.basic.xsl)

Use table_basic.xsl, shown in Sample Auxiliary XSLT File for Constructing a Table. This file builds a basic HTML table for use in Internet Explorer 4.0 (it uses data islands to store a copy of the XML locally). This stylesheet has no "main" root template, and is intended only to be called from another stylesheet as an include.

Formatted Output

Processor Output

See Sample XSLT Processor Output for Constructing a Table.


Sample XML File for Constructing a Table

This is a variant of Sample XML File (books.xml).

XML File (book_catalog.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="bookcatalogtable.xsl"?>
<catalog>
   <book id="bk101">
      <title>XML Developer's Guide</title>
      <author>Gambardella, Matthew</author>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications with XML.</description>
   </book>
   <book id="bk102">
      <title>Midnight Rain</title>
      <author>Ralls, Kim</author>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description>
   </book>
   <book id="bk103">
      <title>Maeve Ascendant</title>
      <author>Corets, Eva</author>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-11-17</publish_date>
      <description>After the collapse of a nanotechnology society in England, the young survivors lay the foundation for a new society.</description>
   </book>
   <book id="bk104">
      <title>Oberon's Legacy</title>
      <author>Corets, Eva</author>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2001-03-10</publish_date>
      <description>In post-apocalypse England, the mysterious agent known only as Oberon helps to create a new life for the inhabitants of London. Sequel to Maeve Ascendant.</description>
   </book>
   <book id="bk105">
      <title>The Sundered Grail</title>
      <author>Corets, Eva</author>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2001-09-10</publish_date>
      <description>The two daughters of Maeve, half-sisters, battle one another for control of England. Sequel to Oberon's Legacy.</description>
   </book>
   <book id="bk106">
      <title>Lover Birds</title>
      <author>Randall, Cynthia</author>
      <genre>Romance</genre>
      <price>4.95</price>
      <publish_date>2000-09-02</publish_date>
      <description>When Carla meets Paul at an ornithology conference, tempers fly as feathers get ruffled.</description>
   </book>
   <book id="bk107">
      <title>Splish Splash</title>
      <author>Thurman, Paula</author>
      <genre>Romance</genre>
      <price>4.95</price>
      <publish_date>2000-11-02</publish_date>
      <description>A deep sea diver finds true love twenty thousand leagues beneath the sea.</description>
   </book>
   <book id="bk108">
      <title>Creepy Crawlies</title>
      <author>Knorr, Stefan</author>
      <genre>Horror</genre>
      <price>4.95</price>
      <publish_date>2000-12-06</publish_date>
      <description>An anthology of horror stories about roaches, centipedes, scorpions  and other insects.</description>
   </book>
   <book id="bk109">
      <title>Paradox Lost</title>
      <author>Kress, Peter</author>
      <genre>Science Fiction</genre>
      <price>6.95</price>
      <publish_date>2000-11-02</publish_date>
      <description>After an inadvertant trip through a Heisenberg Uncertainty Device, James Salway discovers the problems of being quantum.</description>
   </book>
   <book id="bk110">
      <title>Microsoft .NET: The Programming Bible</title>
      <author>O'Brien, Tim</author>
      <genre>Computer</genre>
      <price>36.95</price>
      <publish_date>2000-12-09</publish_date>
      <description>Microsoft's .NET initiative is explored in detail in this deep programmer's reference.</description>
   </book>
   <book id="bk111">
      <title>MSXML3: A Comprehensive Guide</title>
      <author>O'Brien, Tim</author>
      <genre>Computer</genre>
      <price>36.95</price>
      <publish_date>2000-12-01</publish_date>
      <description>The Microsoft MSXML3 parser is covered in detail, with attention to XML DOM interfaces, XSLT processing, SAX and more.</description>
   </book>
   <book id="bk112">
      <title>Visual Studio 7: A Comprehensive Guide</title>
      <author>Galos, Mike</author>
      <genre>Computer</genre>
      <price>49.95</price>
      <publish_date>2001-04-16</publish_date>
      <description>Microsoft Visual Studio 7 is explored in depth, looking at how Visual Basic, Visual C++, C#, and ASP+ are integrated into a comprehensive development environment.</description>
   </book>
</catalog>


Sample XSLT File for Constructing a Table

This file is intended for use with other files. For more information, see Using Design Patterns for Constructing Tables.

XSLT File (bookcatalogtable.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">

<xsl:import href="table.basic.xsl"/>
<xsl:import href="date.xsl"/>
<xsl:output method="xml"/>

<xsl:template match="/">
    <html>
        <head>
            <title>Book Catalog</title>
        </head>
        <body>
            <h1>Book Catalog</h1>
            <xsl:call-template name="table_basic">
                <xsl:with-param name="table.data" select="*"/>
                <xsl:with-param name="id" select="'data'"/>
            </xsl:call-template>
        <style>
.table_basic_row0 {background-color:lightGreen;}
        </style>
        <script language="Javascript">
                function processClick(me){
                    var tableDoc=data.XMLDocument;
                    var item=tableDoc.selectSingleNode("//*[@id='"+me.id+"']");
                    alert("You have selected " + item.selectSingleNode('title').text + " by " + item.selectSingleNode('author').text +".");
                    }

            </script>
        </body>
    </html>
</xsl:template>

<xsl:template match="price" mode="table_basic_cell_contents">
    $<xsl:value-of select="format-number(.,'###,###.00')"/>
</xsl:template>

<xsl:template match="publish_date" mode="table_basic_cell_contents">
    <xsl:call-template name="date.convert">
        <xsl:with-param name="date" select="."/>
    </xsl:call-template>
</xsl:template>

<xsl:template match="title" mode="table_basic_cell_contents">
    <b><xsl:value-of select="."/></b>
</xsl:template>

</xsl:stylesheet>


Sample Auxiliary XSLT File for Constructing a Table

This file is intended for use with other files. For more information, see Using Design Patterns for Constructing Tables.

XSLT File (table.basic.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:template name="table_basic">
    <xsl:param name="table.data"/>
    <xsl:param name="id" select="generate-id()"/>
    <style>
      .table_basic {}
      .table_basic_head_row {background-color:navy;color:white;}
      .table_basic_head_cell {border:outset 3px blue;}
      .table_basic_row0 {background-color:lightBlue;}
      .table_basic_row1 {background-color:white;}
      .table_basic_row_cell {}
    </style>
    <xml id="{$id}">
        <xsl:copy-of select="*"/>
    </xml>

    <xsl:apply-templates select="$table.data" mode="table_basic"/>
</xsl:template>

<xsl:template match="*" mode="table_basic_cell">
   <td class="table_basic_row_cell">
      <xsl:apply-templates select="." mode="table_basic_cell_contents"/>
   </td>
</xsl:template>

<xsl:template match="*" mode="table_basic_row">
  <tr class="table_basic_row{position() mod 2}" onclick="processClick(this)" id="{@id}">
     <xsl:apply-templates select="*" mode="table_basic_cell"/>
  </tr>
</xsl:template>

<xsl:template match="*" mode="table_basic_head_cell">
  <th class="table_basic_head_cell">
     <xsl:value-of select="translate(name(.),'abcdefghijklmnopqrstuvwxyz_','ABCDEFGHIJKLMNOPQRSTUVWXYZ ')"/>
  </th>
</xsl:template>

<xsl:template match="*" mode="table_basic">
   <script language="Javascript">
      function processClick(me){
         var tableDoc=data.XMLDocument;
         var item=tableDoc.selectSingleNode("//*[@id='"+me.id+"']");
         alert(item.xml);
         }

   </script>

   <table class="table" cellspacing="0">
      <tr class="table_basic_head_row">
         <xsl:apply-templates select="*[1]/*" mode="table_basic_head_cell"/>
      </tr>
      <xsl:apply-templates select="*" mode="table_basic_row"/>
   </table>
</xsl:template>

<xsl:template match="*|@*|text()" mode="table_basic_cell_contents">
   <xsl:copy><xsl:apply-templates select="*|@*|text()" mode="table_basic_cell_contents"/></xsl:copy>
</xsl:template>

</xsl:stylesheet>


Sample XSLT Processor Output for Constructing a Table

A portion of the output stream is shown here, with some line breaks and blank lines added for clarity.

<?xml version="1.0" encoding="UTF-16"?>
<html xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<head><title>Book Catalog</title></head>
<body><h1>Book Catalog</h1>

<style>
        .table_basic {}
        .table_basic_head_row {background-color:navy;color:white;}
        .table_basic_head_cell {border:outset 3px blue;}
        .table_basic_row0 {background-color:lightGreen;}
        .table_basic_row1 {background-color:white;}
        .table_basic_row_cell {}
    </style>

<xml id="data">
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications with
 XML.</description>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>A former architect battles corporate zombies,
 an evil sorceress, and her own childhood to become queen of the
 world.</description>
</book>
...
</catalog>
</xml>

<script language="Javascript">
        function processClick(me){
            var tableDoc=data.XMLDocument;
            var item=tableDoc.selectSingleNode("//*[@id='"+me.id+"']");
            alert(item.xml);
            }
    </script>

<table class="table" cellspacing="0">

<tr class="table_basic_head_row">
<th class="table_basic_head_cell">AUTHOR</th>
<th class="table_basic_head_cell">TITLE</th>
<th class="table_basic_head_cell">GENRE</th>
<th class="table_basic_head_cell">PRICE</th>
<th class="table_basic_head_cell">PUBLISH DATE</th>
<th class="table_basic_head_cell">DESCRIPTION</th>
</tr>

<tr class="table_basic_row1" onclick="processClick(this)" id="bk101">
<td class="table_basic_row_cell">
<author>Gambardella, Matthew</author></td>
<td class="table_basic_row_cell">
<b>XML Developer's Guide</b></td>
<td class="table_basic_row_cell">
<genre>Computer</genre></td>
<td class="table_basic_row_cell">
    $44.95</td>
<td class="table_basic_row_cell">October 1,     2000</td>
<td class="table_basic_row_cell">
<description>An in-depth look at creating applications with
 XML.</description></td>
</tr>

<tr class="table_basic_row0" onclick="processClick(this)" id="bk102">
<td class="table_basic_row_cell">
<author>Ralls, Kim</author></td>
<td class="table_basic_row_cell">
<b>Midnight Rain</b></td>
<td class="table_basic_row_cell">
<genre>Fantasy</genre></td>
<td class="table_basic_row_cell">
    $5.95</td>
<td class="table_basic_row_cell">December 16,     2000</td>
<td class="table_basic_row_cell">
<description>A former architect battles corporate zombies,
 an evil sorceress, and her own childhood to become queen of the
 world.</description></td>
</tr>
...
</table>

<style>.table_basic_row0 {background-color:lightBlue;}</style>

<script language="Javascript">
      function processClick(me){
          var tableDoc=data.XMLDocument;
          var item=tableDoc.selectSingleNode("//*[@id='"+me.id+"']");
          alert("You have selected " + item.selectSingleNode('title').text +
                " by " + item.selectSingleNode('author').text +"."); }
      </script>
</body></html>


Creating Selection Boxes Using XSLT Templates

Creating and populating selection boxes is a very common task, and one that can easily be accomplished via XSLT. You can create an XSLT template that can be used to parameterize the selection box routine, allowing you to pass the default value for the box, along with the items that make up the options.

Providing Values and Content for Option Elements

An <option> tag has both the displayed content and the value that is passed as part of a form submit.

Providing an Associated Value for the Selected Attribute

The Selected element is used to indicate that the specific option is the one that's shown in the window (though not necessarily the one that's the value of the <select> element itself. This can, however, cause problems on output in older Netscape browsers.

Using Parameters To Generalize Select Boxes

The Select tag not only produces a drop down box (when the size attribute is set to a value less than 2), but can also be used to set list boxes, potentially with multiple entries. As such it's best to transform the nodeset to a standard form that can be used by the selectBox template, rather than trying to create a generic input form.

Setting Defaults For Parameters

You can set parametric defaults to set key attributes (such as size) to a given default if no parameter is provided. Additionally, you can use the name() function to generalize XPath expressions so that you can compare node-names based upon external parameters.

Example

This example creates a selection box using an internal node-set holding languages, although any homogeneous set of nodes that can be passed as a node-set can be used.

XML File

None. The XSLT file calls itself; view the XSLT file in Internet Explorer.

XSLT File (selectbox.xsl)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="selectbox.xsl" ?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">

<xsl:output omit-xml-declaration="yes"/>
<xsl:variable name="languages.1">
    <language name="cplusplus">C++</language>
    <language name="csharp">C#</language>
    <language name="ecmascript">ECMAScript</language>
    <language name="perl">Perl</language>
    <language name="vb">Visual Basic</language>
    <language name="vbscript">VBScript</language>
</xsl:variable>
<xsl:variable name="languages" select="msxsl:node-set($languages.1)"/>

<xsl:template match="/">
    <xsl:call-template name="selectbox">
        <xsl:with-param name="name" select="'languages'"/>
        <xsl:with-param name="option.name" select="'name'"/>
        <xsl:with-param name="dataset" select="$languages/*"/>
        <xsl:with-param name="size" select="0"/>
        <xsl:with-param name="value" select="'Visual Basic'"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="selectbox">
    <xsl:param name="name"/>
    <xsl:param name="option.name" select="''"/>
    <xsl:param name="dataset"/>
    <xsl:param name="size" select="1"/>
    <xsl:param name="value"/>

    <select name="{$name}" id="{$name}" size="{$size}">
        <xsl:for-each select="$dataset">
            <option>

            <xsl:attribute name="value">
                <xsl:choose>
                    <xsl:when test="$option.name=''">
                        <xsl:value-of select="text()"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="@*[name(.)=$option.name]"/>
                    </xsl:otherwise>
                </xsl:choose>
             </xsl:attribute>

             <xsl:choose>
                 <xsl:when test="$option.name='' and $value=text()">
                 <xsl:attribute
                  name="selected">selected</xsl:attribute>
                 </xsl:when>
                 <xsl:when test="@*[(name(.)=$option.name)
                       and (string(.)=$value)]">
                    <xsl:attribute name="selected">selected</xsl:attribute>
                 </xsl:when>
             </xsl:choose>
             <xsl:value-of select="."/>

            </option>
        </xsl:for-each>
    </select>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

Line breaks added for clarity.

<select name="languages" id="languages" size="0" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<option value="cplusplus">C++</option>
<option value="csharp">C#...</option></select>


Operating on Strings Using an XSLT Utility File

XSLT combines a string manipulation language with a node pattern matching language. It includes a number of simple string functions. Using elements such as string-before() and string-after() you can parse, or separate, string subelements into node-sets, or inversely map node-sets to delimited strings. The string_utils.xsl file referenced here includes a number of string utilities.

  • tokenize - takes a source string and a delimiter string (which can be more than one character long) and splits the source at the delimiters to be placed into XML nodes. This can be used for a number of purposes -- splitting a comma-delimited string, turning return delimited lines of text into text elements, replacing a substring with another string in a block of text, and so forth. Note that tokenize uses recursion, creating a new element then calling the tokenize named template again to extract the next delimited string.
  • nodeset.join - converts a series of XML record elements (with element properties) into a block of comma and carriage return delimited text. Its primary purpose is to generate text files for delimited files, but can be used to generate a fairly wide number of formatted output formats.
  • show_entity_table - enables generating indexed tables. You pass the largest value that you want displayed, and the show_entity_table named template will generate the character set number and the entity associated with that number as part of a table. This template actually uses itself to generate its output.

XSLT File (string_utils.xsl)

You can view this file in Internet Explorer.

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="string_utils.xsl" ?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
   <html>
   <body>
   <h1>Tokenize</h1>

   <xmp>
      <xsl:call-template name="tokenize">
         <xsl:with-param name="source_str"
               select="'C++ C# Ecmascript Perl VB VBScript'"/>
         <xsl:with-param name="delimiter" select="' '"/>
      </xsl:call-template>
   </xmp>

   <xsl:call-template name="show_entity_table"/>
   </body>
   </html>
</xsl:template>

<xsl:template name="tokenize">
   <xsl:param name="source_str"/>
   <xsl:param name="delimiter" select="' '"/>
   <xsl:param name="element_name" select="'item'"/>
   <xsl:variable name="temp_str" select="normalize-space($source_str)"/>

   <xsl:variable name="source_str_1">
   <xsl:choose>
      <xsl:when test="substring($temp_str,string-length($temp_str)
            - string-length($delimiter)
            + 1,string-length($delimiter))!=$delimiter">
          <xsl:value-of select="$temp_str"/>
          <xsl:value-of select="$delimiter"/>
      </xsl:when>
      <xsl:otherwise>
          <xsl:value-of select="$temp_str"/>
      </xsl:otherwise>
   </xsl:choose>
   </xsl:variable>

   <xsl:choose>
       <xsl:when test="contains($source_str_1,$delimiter)">
           <xsl:element name="{$element_name}">
              <xsl:value-of select="substring-before($source_str_1,$delimiter)"/>
           </xsl:element>
       </xsl:when>
       <xsl:otherwise>
           <xsl:if test="$source_str_1!=''">
               <xsl:element name="{$element_name}">
                 <xsl:value-of select="$source_str_1"/>
               </xsl:element>
           </xsl:if>
       </xsl:otherwise>
   </xsl:choose>

   <xsl:variable name="new_string"
         select="substring-after($source_str_1,$delimiter)"/>
   <xsl:if test="not($new_string = '')">
       <xsl:call-template name="tokenize">
           <xsl:with-param name="source_str" select="$new_string"/>
           <xsl:with-param name="delimiter" select="$delimiter"/>
           <xsl:with-param name="element_name" select="$element_name"/>
       </xsl:call-template>
   </xsl:if>
</xsl:template>

<xsl:template match="langmap">
    <xsl:choose>
        <xsl:when test="@lang='GK'">
            <xsl:value-of select="translate(.,'ABGDEZHQIKLMNXOPRSTUFCJWabgdezhqiklmnxoprstufcjw','&#913;&#914;&#915;&#916;&#917;&#918;&#919;&#920;&#921;&#922;&#923;&#924;&#925;&#926;&#927;&#928;&#929;&#931;&#932;&#933;&#934;&#935;&#936;&#937;&#945;&#946;&#947;&#948;&#949;&#950;&#951;&#952;&#953;&#954;&#955;&#956;&#957;&#958;&#959;&#960;&#961;&#963;&#964;&#965;&#966;&#967;&#968;&#969;&#970;')"/>
        </xsl:when>
    </xsl:choose>
</xsl:template>

<xsl:template name="show_entity_table">
    <xsl:param name="entity_row" select="1"/>
    <xsl:param name="final_entity_row" select="64"/>
    <xsl:param name="row_size" select="16"/>

    <h1>show_entity_table</h1>
    <table>
        <xsl:call-template name="show_entity_row">
            <xsl:with-param name="entity_row" select="$entity_row"/>
            <xsl:with-param name="final_entity_row" select="$final_entity_row"/>
            <xsl:with-param name="row_size" select="$row_size"/>
        </xsl:call-template>
    </table>
</xsl:template>

<xsl:template name="show_entity_row">
    <xsl:param name="entity_row" select="0"/>
    <xsl:param name="final_entity_row" select="7"/>
    <xsl:param name="row_size" select="16"/>

    <tr>
    <xsl:call-template name="show_entity_entry">
        <xsl:with-param name="base_pos"
              select="number($entity_row) * number($row_size)"/>
        <xsl:with-param name="offset" select="0"/>
        <xsl:with-param name="row_size" select="$row_size"/>
    </xsl:call-template>
    </tr>

    <xsl:if test="number($entity_row) &lt; number($final_entity_row)">
    <xsl:call-template name="show_entity_row">
        <xsl:with-param name="entity_row" select="number($entity_row)+1"/>
        <xsl:with-param name="final_entity_row" select="$final_entity_row"/>
        <xsl:with-param name="row_size" select="$row_size"/>
    </xsl:call-template>
    </xsl:if>
</xsl:template>

<xsl:template name="show_entity_entry">
        <xsl:param name="base_pos" select="0"/>
        <xsl:param name="offset" select="0"/>
        <xsl:param name="row_size" select="16"/>
        <xsl:variable name="entity_number" select="$base_pos + $offset"/>

    <td><xsl:value-of select="$entity_number"/></td>
    <td>
       <xsl:value-of select="concat('&amp;#',$entity_number,';')"
             disable-output-escaping="yes"/>
    </td>

    <xsl:if test="number($offset) &lt; number($row_size)">
        <xsl:call-template name="show_entity_entry">
            <xsl:with-param name="base_pos" select="$base_pos"/>
            <xsl:with-param name="offset" select="number($offset)+1"/>
            <xsl:with-param name="row_size" select="$row_size"/>
        </xsl:call-template>
    </xsl:if>

</xsl:template>

<xsl:template name="nodeset.join">
    <xsl:param name="nodeset"/>
    <xsl:param name="item.delimiter" select="','"/>
    <xsl:param name="item.delimiter.start" select="''"/>
    <xsl:param name="line.delimiter" select="'&#13;'"/>
    <xsl:param name="line.delimiter.start" select="''"/>
    <xsl:param name="item.delimiter.terminate" select="'no'"/>
    <xsl:param name="nodeset.nameonly" select="'no'"/>

    <xsl:value-of select="$line.delimiter.start"/>
    <xsl:for-each select="$nodeset">
        <xsl:value-of select="$item.delimiter.start"/>

        <xsl:choose>
            <xsl:when test="$nodeset.nameonly='yes'">
                <xsl:value-of select="name(.)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="."/>
            </xsl:otherwise>
        </xsl:choose>

        <xsl:choose>
            <xsl:when test="position()!=last()">
                <xsl:value-of select="$item.delimiter"/>
            </xsl:when>
            <xsl:when test="position()=last()
                  and $item.delimiter.terminate='yes'">
                <xsl:value-of select="$item.delimiter"/>
            </xsl:when>
        </xsl:choose>

    </xsl:for-each>
    <xsl:value-of select="$line.delimiter"/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

A portion of the formatted output is shown below.


Controlling White Space with XSLT

This section covers the following:

  • How White Space is Handled in XML Files
  • How the MSXML Processor Parses White Space
  • Inserting White Space Using <xsl:text>
  • Preserving or Stripping White Space
  • Example of <xsl:preserve-space> and <xsl:strip-space>
  • Overriding <xsl:preserve-space> and <xsl:strip-space>
  • Preserving Markup Characters by Using CDATA Sections
  • Stripping White Space Using normalize-space()
  • Controlling White Space with the DOM
  • How the Browser Handles the preserveWhiteSpace Property
  • Controlling White Space Using the Style Sheet
  • Controlling White Space Using the MSXML Processor

See Also

xsl:strip-space Element

xsl:preserve-space Element


How White Space is Handled in XML Files

White space refers to characters in an XML document, such as spaces and tabs, that are "invisible" when represented in a text editor like Notepad or an application like Microsoft® Internet Explorer.

Character | Entity representation
Space | &#32; (hexadecimal &#x20;)
Carriage return | &#13; (&#xD;)
Tab | &#9; (&#x9;)
Line feed ("newline") | &#10; (&#xA;)

White space includes the tab, space, and line break characters. Any series of white space characters between elements is considered a single whitespace node. For example,

<books>
      <book>

Suppose that between the above elements is a line break, a tab, and some space characters. Together, these characters form a single white space node. If this white space node is stripped, the following results:

<books><book>

If the white space node is normalized, the following single space results:

<books> <book>

If you want the processor to produce human-readable output such as a standard HTML listing, you want to preserve the white space nodes that are contained in the XML input file and the XSLT file.

To control whitespace, use the following XSLT constructs:

&#xA0; or &#160;
<xsl:preserve-space>

A nonbreaking space (&#160;, hexadecimal &#xA0;, or &nbsp; in HTML) is not considered white space because that content is not to be interpreted as a allowable place to break to a new line.

In HTML a nonbreaking space is useful for formatting. If a table cell is completely empty, the inner cell border is not drawn. Putting a nonbreaking space in the cell solves the problem. To achieve that output, use this XSL: <td>&#160;</td>

An HTML-like alternative to writing &#xA0; or &#160; is to define the &nbsp; entity at the top of the XSLT file, as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [<!ENTITY nbsp "&#160;">]>

Then later in the document you can write &nbsp; and it will be recognized the same way as an HTML &nbsp; entity.

You can control white space output in an XML document by using the Document Object Model (DOM) or XSL Transformation (XSLT) features.

Any XML document exercises some control over white space. The parser handles white space in an XML document according to the xml:space attribute and default white space rules before the document is processed by the XSL Transformations (XSLT) processor.

The XML 1.0 specification imposes the following white space rules.

  • Because different operating systems represent line breaks in different ways, as true newlines, carriage returns, linefeed-carriage return character pairs, and so on, any newline characters specific to an operating system are normalized by the parser to a true newline (hex x0A, or decimal 10).
  • The values of attributes (other than CDATA-type attributes) are normalized by replacing multiple consecutive occurrences of white space with a single space. For example, an attribute value such as "text text" with four intervening spaces embedded in the attribute value is passed from the parser as "text text"; the multiple spaces in the original value are replaced with a single space.

If an xml:space attribute in the source XML document or style sheet conflicts with explicit XSLT white space handling, the behavior associated with that xml:space attribute always takes precedence.

According to the XSLT specification, the XSLT processor merges adjacent text nodes into a single text node. (This release of the Microsoft XSLT processor does not implement this feature.) If a text node (following any merging that occurs) consists of white space only, the containing element is compared to the list of elements in any <xsl:strip-space> elements in the style sheet. If the containing element appears in such a list, the white space-only text node is removed from the result tree.

This applies only to insignificant white space, that is, white space between, not within, elements. Use the XSLT normalize-space() function to normalize white space within elements.

White space is handled by the Microsoft® XML Parser (MSXML) as a whole — by its built-in parser as well as its built-in XSLT processor.

See Also

White Space (XML Developer's Guide)

Controlling White Space with XSLT

xsl:preserve-space Element

xsl:strip-space Element


How the MSXML Processor Parses White Space

The Microsoft® XML Parser (MSXML) or processor is at the heart of XML-related processing in Microsoft Internet Explorer, and can be used through scripts and programming languages such as Microsoft Visual C++®. This section describes the general functioning of MSXML, particularly as it relates to processing white space in XSL Transformations (XSLT).

The XML 1.0 specification describes an XML processor as a software application that reads an XML file or stream and ensures its legitimacy as XML. This legitimacy is of two kinds: well-formedness, performed on all XML documents, and validity, performed on XML documents that reference a document type definition (DTD). In other words, an XML processor is an XML parser.

MSXML contains a built-in parser that performs all the functions of a conformant XML 1.0 parser, including white space handling in an XML document. All white space in the document is preserved and passed to a downstream application.

The built-in XSLT processor is not the downstream application that receives the output of the MSXML parser. This can be confusing to developers who are new to MSXML. The following diagram shows an intervening step that receives the parser's output and builds a Document Object Model (DOM) tree, caching it in memory for ready access later.

This has great significance for the way the XSLT processor handles white space in the "input document" it is working with, because this input document is actually the DOM tree in memory — and by default, the Microsoft DOM tree builder removes extraneous white space from the document as passed to it by the parser.

"Extraneous" here refers to any content that is not in the scope of an xml:space attribute whose value is "preserve". The MSXML processor honors the xml:space="preserve" attribute as expected.

In order to override this default and retain the original document's extraneous white space in the DOM tree, you must set the preserveWhiteSpace property to True at the time the DOM is loaded. In other words, preserving the original document's extraneous or insignificant white space cannot be accomplished using XSLT features alone. By the time the XSLT processor sees what it thinks is the document, all such white space has, by default, been stripped.

The only way to set the preserveWhiteSpace property to True is through script or programming language DOM processing. For more information, see White Space and the DOM.


Inserting White Space Using <xsl:text>

The <xsl:text> element sends literal text to the output stream. Because this element forces any white space information within it to be retained, it can be used to send multiple white space characters (those entered directly by keyboard or represented as entities) as part of a string of text.

The way the white space in the document is treated by the XSL Transformations (XSLT) processor depends on the white space it receives from the Microsoft® Document Object Model (DOM) processor. Bear this in mind as you follow the examples in this section.

Example

In this example, the first pair of <xsl:value-of> elements are separated by four simple spaces. This white space-only text node is stripped from the result tree by the XSLT processor. In the second pair of <xsl:value-of> elements, however, the four spaces are preserved by the <xsl:text> element. The following is the HTML generated by these sections of the style sheet.

White space stripped:&lt;-here<br>

White space preserved: &lt;-here

Note that four spaces are retained in the second line. However, Internet Explorer, following standard browser behavior, normalizes multiple spaces in an HTML document to a single space on output.

XML File

None. The XSLT file calls itself; view the XSLT file in Internet Explorer.

XSLT File (whitespace1.xsl)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="whitespace1.xsl" ?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<html>
<head><title>Test for WhiteSpace1.xsl</title></head>
<body>
<!-- Put literal text in the result tree: a phrase, four
spaces, and the word "Testing." -->
<xsl:value-of select="'White space stripped:'"/>    <xsl:value-of select="'&lt;-here'"/><br/>
<!-- Put literal text in the result tree: a phrase, four
spaces, and the word "Testing." This time, though,
enclose the four spaces in an <xsl:text> element. -->
<xsl:value-of select="' White space preserved:'"/>
<xsl:text>    </xsl:text>
<xsl:value-of select="'&lt;-here'"/>
</body>
</html>
</xsl:template>

</xsl:stylesheet>

Formatted Output

White space stripped:<-here
White space preserved: <-here

Processor Output

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-16">
<title>Test for WhiteSpace1.xsl</title></head>
<body>White space stripped:&lt;-here<br> White space preserved: &lt;-here</body>
</html>

See Also

Character and Entity References


Preserving or Stripping White Space

XSL Transformations (XSLT) can distinguish nodes that contain white space intermingled with other characters. The white space is considered inseparable from the other text in the node.

For nodes that contain nothing but white space, the <xsl:preserve-space> and <xsl:strip-space> elements handle how the nodes are output.

Preserving White Space with <xsl:preserve-space>

The <xsl:preserve-space> element provides a list of those elements in the source document where white space must be preserved on output. <xsl:preserve-space> is always an empty, top-level element, for example, a child of the <xsl:stylesheet> element in an XSLT style sheet.

The following is the general syntax.

<xsl:preserve-space elements="elem1 elem2..." />

elem1 and elem2 are the names of all elements (without the enclosing < and > delimiters) whose white space must be preserved.

You can specify all of the elements in the source document with the asterisk operator ("*").

<xsl:preserve-space elements="*" />

Because all of the content of an XML document is, by default, preserved, <xsl:preserve-space> is useful only in cases in which you have used <xsl:strip-space> to override the default behavior; in such cases, use <xsl:preserve-space> to identify exceptions to the explicit stripping of white space.

Note The Microsoft® XSLT processor will process all of a document's white space only if the preserveWhiteSpace property has been set to True prior to loading the document into the DOM. For more information, see How the MSXML Processor Parses White Space.

Removing White Space with <xsl:strip-space>

The <xsl:strip-space> element provides a list of those elements in the source document in which content must be removed from the output tree. <xsl:strip-space> is an empty, top-level element.

The following is the general syntax.

<xsl:strip-space elements="elem1 elem2..." />

elem1 and elem2 are the names of all elements (without the enclosing < and > delimiters) whose white space must be removed.

You can specify all of the elements in the source document with the asterisk operator ("*").

<xsl:strip-space elements="*" />

If an element appears in both an <xsl:strip-space> and <xsl:preserve-space> list, the last specification applies. Therefore, a typical sequence of these two elements in an XSLT style sheet is as follows.

<xsl:strip-space elements="*" />
<xsl:preserve-space elements="elem1 elem2..." />

If this order were reversed, the explicit "preserve" settings for elem1, elem2, and so on would be overridden by the global "strip" setting.


Example of <xsl:preserve-space> and <xsl:strip-space>

You can use the <xsl:preserve-space> and <xsl:strip-space> elements to preserve and strip white space from XML documents. The following strippreserve.xml document contains <code> and <block> elements that have white space in the form of tabs, spaces, and newline characters. The strippreserve.xsl style sheet is applied to the strippreserve.xml document to retain white space within all <code> elements and to strip it from all the block elements.

In the strippreserve.xml document, the first <code> element and first <block> element contain exactly the same amount and kind of white space (a single space), as do the second <code> and <block> elements. However, the second <code> and second <block> elements also contain the phrase "Some text" among the white space. For the strippreserve.xml document, the <?xml-stylesheet type="text/xsl" href="strippreserve.xsl" ?> instruction is included to apply the strippreserve.xsl style sheet to the strippreserve.xml document. When applied, the strippreserve.xsl style sheet causes the <code> elements to retain white space-only content and the <block> elements to lose white space-only content.

Example

The strippreserve.xsl style sheet below does the following.

  • Preserves the extraneous white space in the <code> elements.
  • Strips the extraneous white space from the <block> elements.
  • Encloses the content of each <code> and <block> element in square brackets, [ ].
  • Provides a numbered label for each <code> or <block> using the XSL Transformations (XSLT) position() function.
  • Using the XML Path Language (XPath) translate() function, converts "invisible" white space to a visible character, one character at a time. This enables you to "see" the specific white characters in the <code> and <block> elements.

Each space character appears in the result tree as a hyphen (-).

Each newline character appears in the result tree as the letter "N."

Each carriage return appears in the result tree as the letter "R."

Each tab appears in the result tree as the letter "T."

The first <code> element contains a single space, denoted by the hyphen in the [ ] characters. The first <block> element also contains a single space in the source document. However, the <xsl:strip-space> setting has caused this space to be removed from the result tree.

In the second <code> and <block> elements, no white space has been removed. If an element has any non-white space content, white space will not be stripped even if <xsl:strip-space> is set for that element.

Note This represents a "pure XSLT" approach to the stripping and retention of white space. You can also strip or retain white space by manipulating the Document Object Model (DOM). For more information about this approach, see White Space and the DOM.

XML File (strippreserve.xml)

Copy this text to a file, then find and replace each "tabhere" by a tab (press the Tab key).

<?xml-stylesheet type="text/xsl" href="strippreserve.xsl" ?>
<document>
<block> </block>
<block>
tabhere
Some texttabhere
tabhere
tabhere</block>
<code> </code>
<code>
tabhere
Some texttabhere
tabhere
tabhere</code>
</document>

XSLT File (strippreserve.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- Retain white space within all <code> elements -->
<xsl:preserve-space elements="code"/>
<!-- ... but strip it from all <block> elements -->
<xsl:strip-space elements="block"/>

<xsl:template match="/">
<html>
<head><title>Test: Stripping/Preserving White Space</title></head>
<body>
<h4>Code blocks:</h4>
<!-- <pre> element forces all output characters to be same width -->
<pre>
<!-- Use translate() XPath function to convert white-space
           characters to "visible" form. -->
<xsl:for-each select="//code">
"Code" #<xsl:value-of select="position()"/>: [<xsl:value-of select="translate(.,' &#10;&#13;&#9;','-NRT')"/>]<br/>
</xsl:for-each>
</pre>
<h4>Normalized blocks:</h4>
<pre>
<xsl:for-each select="//block">
"Block" #<xsl:value-of select="position()"/>: [<xsl:value-of select="translate(.,' &#10;&#13;&#9;','-NRT')"/>]<br/>
</xsl:for-each>
</pre>
</body>
</html>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Code blocks:

"Code" #1: [-]

"Code" #2: [NTNSome-textTNTNT]

Normalized blocks:

"Block" #1: []

"Block" #2: [NTNSome-texttabhereNTNT]

Processor Output

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-16">
<title>Test: Stripping/Preserving White Space</title></head>
<body>
<h4>Code blocks:</h4>
<pre>
"Code" #1: [-]<br>
"Code" #2: [NTNSome-textTNTNT]<br></pre>
<h4>Normalized blocks:</h4>
<pre>
"Block" #1: []<br>
"Block" #2: [NTNSome-textTNTNT]<br></pre>
</body>
</html>


Overriding <xsl:preserve-space> and <xsl:strip-space>

Use the xml:space attribute to override the effect of <xsl:strip-space> or <xsl:preserve-space>. When applied to a white space-only <xsl:text> node within an element otherwise marked to have its spaces stripped or preserved, xml:space indicates whether the white space content contained within the <xsl:text> element should be preserved. For example, even though the <block> elements in a previous example (Inserting White Space Using <xsl:text>) were specified in the <xsl:strip-space> element list, you can force the preservation of four spaces by including the following in that template rule.

<block><xsl:text xml:space="yes">     </xsl:text></block>

This example is artificial in that it forces the insertion of white space within the style sheet. It does not restore or preserve white space in the original document. To do that, you must override the default stripping of extraneous white space by setting the preserveWhiteSpace property to True at the time the document is loaded into the Document Object Model (DOM).

See Also

Preserving or Stripping White Space | How the MSXML Processor Parses White Space | White Space and the DOM


Preserving Markup Characters by Using CDATA Sections

CDATA sections allow you to use sequences of characters within an XML stream that contain markup elements common to XML without violating XML well-formedness constraints. For example, a mathematical XML application using < and > characters to refer to "less-than" and "greater-than" can use a CDATA section.

You can specify that a given element in the result tree will contain a CDATA section by including it in the cdata-section-elements attribute of the <xsl:output> element. The CDATA section created in this way will preserve white space and character entities.

Note Although the current release of the Microsoft® XML Parser (MSXML) preserves extraneous white space in CDATA sections, this behavior is likely to change in a future release in order to conform to the XML 1.0 specification.

Example

The XSL Transformations (XSLT) processor scans the result tree, making a CDATA section of each item in the cdata-section-elements attribute.

To create the CDATA section, the elements listed as values of the cdata-section-elements attribute must be elements in the result tree, not the source tree. In the preceding examples, the Microsoft JScript® code appears as a text node within the source tree's <scriptcode> element, but the cdata-section-elements attribute refers to and affects <script> elements in the result tree.

HTML does not recognize CDATA sections. Do not use this option when generating HTML.

XML File (cdata.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="cdata.xsl" ?>
<document>
<scriptcode language="JScript">
function message(msg){
alert(msg);
}
</scriptcode>
</document>

XSLT File (cdata.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output cdata-section-elements="script"/>

<xsl:template match="scriptcode">
<document>
<script language="JScript">
<xsl:value-of select="."/>
</script>
</document>
</xsl:template>

</xsl:stylesheet>

Formatted Output

None; blank.

Processor Output

<?xml version="1.0" encoding="UTF-16"?><document><script language="JScript"><![CDATA[
function message(msg){
alert(msg);
}
]]></script></document>

See Also

CDATA Sections


Stripping White Space Using normalize-space()

XSL Transformations (XSLT) provides a built-in function, normalize-space(), that strips leading and trailing white space from a string and normalizes multiple successive white space characters to a single space. It takes one argument, a string or node-set (the latter being converted to a string as necessary); if the argument is omitted, normalize-space() assumes the context node.

The following is an XML fragment with leading newline and tab characters following the <generouswhitespace> start tag. There are 10 trailing spaces and a newline preceding the </generouswhitespace> end tag.

<generouswhitespace>
There is a l     o    t of white         space here!
</generouswhitespace>

This fragment's white space can be normalized with the following XSLT template rule, which encloses the <generouswhitespace> element's text content in [ ] characters.

<xsl:template match="generouswhitespace">
[<xsl:value-of select="normalize-space(.)" />]
</xsl:template>

The output appears as follows.

[There is a l o t of white space here!]

All leading white space has been trimmed, and each block of extraneous white space within the text node has been "squeezed" down to a single space.


Controlling White Space with the DOM

When a text file is opened with the xmlDoc.load or xmlDoc.loadXML methods (where xmlDoc is an XML DOM document), the parser strips most white space from the file unless specifically directed otherwise; the parser notes within each node whether one or more spaces, tabs, newlines, or carriage returns follow the node in the text by setting a flag. This method is efficient, reducing both the size of each XML file and the number of calculations required to redisplay the XML in a browser. However, because this information is lost, an XML document stored in this manner can lose formatting information in its content. Tabs, in particular, can be lost because they are not formally recognized in the default mode as anything but white space.

XSL Transformations (XSLT) use the XML Document Object Model (DOM), not the source document, to guide the transformation. Because the white space has already been stripped to process the XML into the DOM, white space characters are lost even before the transformation takes place. Most of the XSLT-related methods for specifying white space in the source data document or style sheets are applied too late to make a difference in formatting.

The preserveWhiteSpace property tells the XML parser whether or not to convert white space from the initial source file that acts against the XML DOM. If explicitly set (the default is False), it must always be set prior to loading a file; otherwise, the default is to strip white space characters and reduce the file to the smallest possible stream. When preserveWhiteSpace is set to True, the XML document retains all of the characters within the file when converted into a DOM; when set to False, the white space characters are stripped from the file.

If you set the preserveWhiteSpace property from True to False then back to True for a given DOM document, the spaces will not reappear — setting the property to False actually removes the space from the DOM, which cannot reconstruct it.

If you are working with XML as a data format streamed to some other process, disable preserveWhiteSpace by setting it, or allowing it to default, to False. If retaining positional information is important, for example, in conversions to non-XML formats like tab-separated data, set preserveWhiteSpace to True. Be aware this option increases the number of characters and places more demands on the browser.

Example

This example shows how white space can be programatically controlled using the DOM. To run the example, view the HTML file in Internet Explorer.

In the first block of the results, the contents of each of the original <whitespace> elements appear on a separate line. In the second block, where the preserveWhiteSpace property is set to False, all contents of these elements appear on a single line. In addition, the first block is indented, while the second block is not. The indents and line breaks in the first block are a result of newline and tab characters in the source document between the boundaries of the <whitespace> elements. This white space is affected by the preserveWhiteSpace property.

The white space within the <whitespace> elements is not affected by the value of the preserveWhiteSpace property. To remove white space-only text children of elements, use the XML Path Language (XPath) normalize-space() function.

The example uses three files:

striporpres.xml
The XML source document. Each of the <whitespace> elements contain different kinds of white space, including tags, spaces, and newlines.
striporpres.xsl
An XSLT style sheet that makes invisible white space visible for demonstration purposes. The striporpres.xsl style sheet consists of two template rules. The first rule applies to the source document root node, instantiating an HTML <pre> element node in the result tree. The transformation of the <whitespace> elements are placed in this node, which is handled by the second template rule. Like the <xsl:strip-space> and <xsl:preserve-space> example, the XML Path Language (XPath) translate() function is used to make the invisible white space visible.
striporpres.htm
An HTML file that contains Microsoft® JScript®. The JScript function preserveStripPreserve is called when the file is loaded. This function:
  • Sets the preserveWhiteSpace property.
  • Loads striporpres.xml and striporpres.xsl into separate DOMDocument objects.
  • Alternately sets the preserveWhitespace property of the DOMDocument object to True or False.

The JScript also applies the striporprres.xls style sheet to the striporpres.xml document using the transformNode method and assigns the resulting string to the innerHTML property, which is used to display the results in Microsoft Internet Explorer.

XML File (striporpres.xml)

There is no <?xml-stylesheet?> processing instruction. Instead, a style sheet is applied programatically to the document using the transformNode method. Unlike a "pure XSLT" solution, this technique allows you to set and reset the preserveWhiteSpace property.

Find and replace each "tabhere" by a tab character (press the Tab key).

<?xml version='1.0'?>
<whitespaceTest>
    <whitespace>Tabs[tabheretabhere]</whitespace>
    <whitespace>Spaces[  ]</whitespace>
    <whitespace>Newlines[

]</whitespace>
</whitespaceTest>

XSLT File (striporpres.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <pre>
      <xsl:apply-templates />
   </pre>
</xsl:template>

<xsl:template match="whitespace">
   <!-- Use translate() XPath function to convert
        character X to character Y. -->
   <xsl:value-of select="translate(.,' &#10;&#13;&#9;','-NRT')"/>
</xsl:template>

</xsl:stylesheet>

HTML File (striporpres.htm)

<html>
<head>
<title>Demo: Controlling White Space Output via the DOM</title>
<script language='JScript'>
<!--
function preserveStripPreserve() {
// Associate the result tree object with any element(s) whose
// id attribute is "testResults."
var objResTree = document.all['testResults'];
// Declare two new Msxml DOMDocument objects.
var objSrcTree = new ActiveXObject('Msxml2.DOMDocument');
var objXSLT = new ActiveXObject('Msxml2.DOMDocument');
// Load the two DOMDocuments with the XML document and the
// XSLT style sheet.
objSrcTree.preserveWhiteSpace = true;
objSrcTree.load('stripOrPres.xml');
objXSLT.load('stripOrPres.xsl');
// Use the transformNode method to apply the XSLT to the XML.
strResult = objSrcTree.transformNode(objXSLT);
// Now reset preserveWhiteSpace to false, and re-load the source...
objSrcTree.preserveWhiteSpace = false;
objSrcTree.load('stripOrPres.xml');
// ...and rerun the transform. Note the concatenation of the
// this transformation's result tree to the one created when
// preserveWhiteSpace was true.
strResult = strResult + objSrcTree.transformNode(objXSLT);
// Assign the resulting string to the result tree object's
// innerHTML property.
objResTree.innerHTML = strResult;
return true;
}
-->
</script>
<body onload='preserveStripPreserve()'>
<div id='testResults'></div>
</body>
</html>

Formatted Output

    Tabs[TT]
    Spaces[--]
    Newlines[NN]
Tabs[TT]Spaces[--]Newlines[NN]

Processor Output

No XSLT processor output stream is available in Internet Explorer for this example.

See Also

Example of <xsl:preserve-space> and <xsl:strip-space> | Stripping White Space Using normalize-space()


How the Browser Handles the preserveWhiteSpace Property

If you have HTML presented as well-formed XML, the preserveWhiteSpace property should have no impact on the Web page displayed in the browser. HTML browsers automatically remove excess white space upon display unless it is contained in <pre></pre> (preserve) or <xmp></xmp> (example) tags.

In the MSXML 3.0 processor, if preserveWhiteSpace is set or defaulted to False, the XSL Transformations (XSLT) white space features will have no effect. In addition, for Microsoft Internet Explorer 5.0 and later, the XML parser is set to ignore unnecessary white space from XSLT transformations. (In other words, preserveWhiteSpace is set to False). To see these results, you must first transform the output through an Active Server Page (ASP) or Microsoft JScript® script or a similar mechanism; you cannot rely on XSLT alone to see the result of most of the white space options.


Controlling White Space Using the Style Sheet

White space-only nodes in the XSL Transformations (XSLT) style sheet, as opposed to those in the source document, are stripped by the XSLT processor.

It can be an advantage to have extraneous white space stripped from a style sheet. You can format the style sheet for easy readability and maintenance, knowing that extra tabs, newlines, and so on will not appear in the result tree.

However, this can be a disadvantage in those cases in which you need white space of a particular kind in the result tree. For example, if you had to insert a blank space in a table cell, you might expect the following.

<td> </td>

However, if your style sheet places this sequence of text as-is in the result tree, it will appear as follows.

<td></td>

Not all browsers will display a "null" cell properly.

Use the <xsl:text> element around any white space-only text nodes.

<td><xsl:text> </xsl:text></td>

For more information, see Inserting White Space Using <xsl:text>.


Controlling White Space Using the MSXML Processor

In most cases, the behavior of the Microsoft® XML Parser (MSXML) processor conforms to white space handling rules imposed by the XML and XSL Transformations (XSLT) specifications.

The following are the exceptions.

  • Adjacent text nodes are not treated as one node. Adjacent text nodes can appear if:
    • The user inserts them into the tree through the Document Object Model (DOM) application programming interface (API).
    • CDATA sections border #PCDATA nodes.
    • An entity reference containing text borders a #PCDATA or CDATA node. (Character references, such as &#10; to represent a newline, are automatically expanded by the parser and handled correctly.)

    Few style sheets will encounter any of these conditions. Furthermore, even if adjacent text nodes exist, users seldom query for text nodes directly. (In most cases, users obtain text nodes by referring to element and attribute nodes.)

  • When the preserveWhitespace property is False, the white space stripped by the DOM is reduced to flags that mark where white space existed. These flags are used to output extra white space when <xsl:copy-of> is used or when the text value of a node is retrieved. These flags act as "virtual" nodes that cannot be queried, but nevertheless behave like text nodes with a value of &#x10; (newline) on output. This does not occur if preserveWhitespace is True because flags are not used.
  • CDATA nodes containing only white space are never stripped.

Behavior that does not conform to XML and XSL specifications will be corrected in a future release of the MSXML processor.


XSLT Reference

The World Wide Web Consortium (W3C) Recommendation for XSL Transformations (XSLT) specifies a transformation language for XML documents. The Microsoft® XML Parser (MSXML) supports this transformation language, XSL Transformations (XSLT) Version 1.0 (W3C Recommendation 16 November 1999). Microsoft plans to update this technology to full compliance with this recommendation.

You can use XSLT from the XML Document Object Model (DOM). The transformNode method, transformNodeToObject method as well as the IXSLProcessor object support the use of XSLT elements to perform transformations. The DOM selectNodes method and selectSingleNode method support the XML Path Language (XPath) expression syntax that enables sophisticated queries for nodes within a particular context of the overall tree structure.

Microsoft Visual Basic® and C++ developers should refer to the following versions of the previously mentioned methods.

  • transformNode
  • transformNodeToObject
  • selectNodes
  • selectSingleNode

The XSLT Reference covers the following:

  • XSLT Elements
  • XSLT Syntax
  • XSLT Functions
  • XPath Syntax
  • XPath Functions

See Also

transformNode Method | transformNodeToObject Method | selectNodes Method | selectSingleNode Method | Template-Driven Transformations | Supported Features in XSLT Releases

Other Resources Other Resources

XSL Transformations (XSLT) Version 1.0 (W3C Recommendation 16 November 1999)


XSLT Elements

XSL Transformations (XSLT) can be used to manipulate, sort, and filter XML data. Many transformations will target well-formed HTML. Well-formed means that any HTML tag can be used, subject to the stricter syntax rules of XML — all start tags are paired with end tags and are nested correctly. Well-formed HTML can be displayed by the browser, or further manipulated by XML tools. The Worldwide Web Consortium (W3C) currently has a recommendation for making the next generation of HTML an XML application. The W3C XHTML™ 1.0: The Extensible HyperText Markup Language describes the benefits of defining well-formed HTML. XSLT is a valuable tool for generating well-formed HTML or other XML files.

XSLT enables you to define templates for your output, into which data from the XML source is delivered. Each template defines a pattern that identifies elements in the source tree and defines the resulting output subtree to be generated. The XSLT transformation processor merges data from the XML source document with the template. By combining a set of template fragments into a style sheet, XSLT can be used to perform data-driven transforms useful for highly irregular XML data and XML documents.

XSLT templates are defined using a small set of XML elements.

XSLT Elements

xsl:apply-imports | Invokes an overridden template rule.
xsl:apply-templates | Directs the XSLT processor to find the appropriate template to apply, based on the type and context of each selected node.
xsl:attribute | Creates an attribute node and attaches it to an output element.
xsl:attribute-set | Defines a named set of attributes.
xsl:call-template | Invokes a template by name.
xsl:choose | Provides multiple conditional testing in conjunction with the <xsl:otherwise element> and <xsl:when element>.
xsl:comment | Generates a comment in the output.
xsl:copy | Copies the current node from the source to the output.
xsl:copy-of | Inserts subtrees and result-tree fragments into the result tree.
xsl:decimal-format | Declares a decimal-format, which controls the interpretation of a format pattern used by the format-number function.
xsl:element | Creates an element with the specified name in the output.
xsl:fallback | Calls template content that can provide a reasonable substitute to the behavior of the new element when encountered.
xsl:for-each | Applies a template repeatedly, applying it in turn to each node in a set.
xsl:if | Allows simple conditional template fragments.
xsl:import | Specifies an XSLT style sheet to include.
xsl:include | Specifies another XSLT style sheet to include.
xsl:key | Declares a named key for use with the key () function in XML Path Language (XPath) expressions.
xsl:message | Sends a text message to either the message buffer or a message dialog box.
xsl:namespace-alias | Replaces the prefix associated with a given namespace with another prefix.
xsl:number | Inserts a formatted number into the result tree.
xsl:otherwise | Provides multiple conditional testing in conjunction with the <xsl:choose element> and <xsl:when element>.
xsl:output | Specifies options for use in serializing the result tree.
xsl:param | Declares a named parameter for use within an xsl:stylesheet or xsl:template. Allows specification of a default value.
xsl:preserve-space | Preserves white space in a document.
xsl:processing-instruction | Generates a processing instruction in the output.
msxsl:script * | Defines global variables and functions for script extensions.
xsl:sort | Specifies sort criteria for node lists selected by xsl:for-each or xsl:apply-templates.
xsl:strip-space | Strips white space from a document.
xsl:stylesheet | The document element of a style sheet, containing all other style sheet elements.
xsl:template | Defines a reusable template for generating the desired output for nodes of a particular type and context.
xsl:text | Generates text in the output.
xsl:transform | Synonym for xsl:stylesheet.
xsl:value-of | Inserts the value of the selected node as text.
xsl:variable | Specifies a value bound in an expression.
xsl:when | Provides multiple conditional testing in conjunction with the <xsl:choose element> and <xsl:otherwise element>.
xsl:with-param | Passes a parameter to a template.

* Microsoft proprietary extensions to support scripting

See Also

Displaying XML Files in Internet Explorer | format-number Function | xsl:apply-templates Element | xsl:choose Element | xsl:for-each Element | xsl:otherwise Element | xsl:stylesheet Element | xsl:template Element | xsl:when Element

Other Resources Other Resources

XHTML™ 1.0: The Extensible HyperText Markup Language


xsl:apply-imports Element

Invokes an overridden template rule.

<xsl:apply-imports />

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:attribute, xsl:comment, xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:processing-instruction, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | (No child elements)

Remarks

A template rule that is being used to override a template rule in an imported style sheet can use the <xsl:apply-imports> element to invoke the overridden template rule.

At any point in the processing of a style sheet, there is a current template rule. Whenever a template rule is chosen by matching a pattern, the template rule becomes the current template rule for the instantiation of the rule's template. When an <xsl:for-each> element is instantiated, the current template rule becomes null for the instantiation of the content of the <xsl:for-each> element.

<xsl:apply-imports> processes the current node using only template rules that were imported into the style sheet element containing the current template rule; the node is processed in the current template rule's mode. It is an error if <xsl:apply-imports> is instantiated when the current template rule is null.

Example

This example demonstrates how you use <xsl:apply-imports> when you want to add to the functionality of the rule in the imported module, but you don't want to replace it entirely. This example uses two stylesheets:

  • The sample.xsl stylesheet sets the font as Arial and imports the other style sheet. When a book element is found, the Arial font is applied to the elements in the node. Then the <xsl:apply-imports> tag applies the matching rules in the imported sample-import stylesheet.
  • The sample-import.xsl stylesheet is the imported style sheet. It provides line breaks, and the formatting for bold, italic, and blue text.

XML File (books.xml)

Use the Sample XML File (books.xml). Below the line <?xml version='1.0'?>, add the following line:

<?xml-stylesheet type="text/xsl" href="sample.xsl"?>

XSLT File (sample.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="sample-import.xsl"/>
<xsl:output method="html"/>

<xsl:template match="book">
   <font face="Arial">
      <xsl:apply-imports/>
   </font>
</xsl:template>

</xsl:stylesheet>

Imported XSLT File (sample-import.xsl)

This file formats the Arial text with bold and italics, and provides line breaks.

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<!-- Override built-in template -->
<xsl:template match="text()"/>

<xsl:template match="/">
  <html>
    <body>
      <xsl:apply-templates/>
    </body>
  </html>
</xsl:template>

<xsl:template match="book">
  <i>
    <xsl:apply-templates select="title"/>
  </i>
    <xsl:text> By: </xsl:text>
  <xsl:apply-templates select="author"/>
  <br/>
</xsl:template>

<xsl:template match="title">
  <b>
    <xsl:value-of select="."/>
  </b>
</xsl:template>

<xsl:template match="author">
  <font color="blue">
    <xsl:value-of select="."/>
  </font>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

<html>
<body>
<font face="Arial"><i><b>XML Developer's Guide</b></i> By: <font color="blue">Gambardella, Matthew</font><br></font>
<font face="Arial"><i><b>Midnight Rain</b></i> By: <font color="blue">Ralls, Kim</font><br></font>
...
<font face="Arial"><i><b>Visual Studio 7: A Comprehensive Guide</b></i> By: <font color="blue">Galos, Mike</font><br></font>
</body>
</html>

See Also

xsl:import Element


xsl:apply-templates Element

Directs the XSL Transformations (XSLT) processor to find the appropriate template to apply, based on the type and context of each selected node.

<xsl:apply-templates
  select = expression
  mode = QName>
</xsl:apply-templates>

Attributes

select
Can be used to process nodes selected by an expression instead of processing all children. The value of the select attribute is an expression. The expression must evaluate to a node-set. The selected set of nodes is processed in document order unless a sorting specification is present.
mode
The mode attribute allows an element to be processed multiple times, each time producing a different result. If <xsl:template> does not have a match attribute, it must not have a mode attribute. If an <xsl:apply-templates> element has a mode attribute, it applies only to those template rules from <xsl:template> elements that have a mode attribute with the same value; if an <xsl:apply-templates> element does not have a mode attribute, it applies only to those template rules from <xsl:template> elements that do not have a mode attribute.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:attribute, xsl:comment, xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:processing-instruction, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | xsl:sort, xsl:with-param

Remarks

The <xsl:apply-templates> element first selects a set of nodes using the query specified in the select attribute. If this attribute is left unspecified, all children of the current node are selected. For each of the selected nodes, <xsl:apply-templates> directs the XSLT processor to find an appropriate <xsl:template> to apply. Templates are tested for applicability by comparing the node to the XPath expression specified in the template's match attribute. If more than one template satisfies the match pattern, the one appearing with the highest priority is chosen. If several templates have the same priority, the last in the style sheet is chosen.

For more information, see Handling Irregular Data Hierarchies.

Example

The following style sheet formats customer data in XML into an HTML <TABLE> element, where each row represents a customer and the columns represent the customer's name, address, and phone number. The <xsl:sort> element sorts the customers by state, with all customers from a single state sorted by name.

XML File (customers.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="applyt.xsl" ?>
<customers>
   <customer>
      <name>John Smith</name>
      <address>123 Oak St.</address>
      <state>WA</state>
      <phone>(206) 123-4567</phone>
   </customer>
   <customer>
      <name>Zack Zwyker</name>
      <address>368 Elm St.</address>
      <state>WA</state>
      <phone>(206) 423-4537</phone>
   </customer>
   <customer>
      <name>Albert Aikens</name>
      <address>368 Elm St.</address>
      <state>WA</state>
      <phone>(206) 423-4537</phone>
   </customer>
   <customer>
      <name>Albert Gandy</name>
      <address>6984 4th St.</address>
      <state>WA</state>
      <phone>(206) 433-4547</phone>
   </customer>
   <customer>
      <name>Peter Furst</name>
      <address>456 Pine Av.</address>
      <state>CA</state>
      <phone>(209) 765-4321</phone>
   </customer>
   <customer>
      <name>Dan Russell</name>
      <address>9876 Main St.</address>
      <state>PA</state>
      <phone>(323) 321-7654</phone>
   </customer>
</customers>

XSLT File (applyt.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:template match="/">
   <HTML>
      <BODY>
         <TABLE border="1" cellspacing="0" cellpadding="2">
            <xsl:apply-templates select="customers/customer">
               <xsl:sort select="state"/>
               <xsl:sort select="name"/>
            </xsl:apply-templates>
         </TABLE>
      </BODY>
   </HTML>
</xsl:template>

<xsl:template match="customer">
   <TR>
      <xsl:apply-templates select="name" />
      <xsl:apply-templates select="address" />
      <xsl:apply-templates select="state" />
      <xsl:apply-templates select="phone" />
      <xsl:apply-templates select="phone" mode="accountNumber"/>
   </TR>
</xsl:template>

<xsl:template match="name">
   <TD STYLE="font-size:14pt font-family:serif">
      <xsl:apply-templates />
   </TD>
</xsl:template>

<xsl:template match="address">
   <TD> <xsl:apply-templates /> </TD>
</xsl:template>

<xsl:template match="state">
   <TD> <xsl:apply-templates /> </TD>
</xsl:template>

<xsl:template match="phone">
   <TD> <xsl:apply-templates /> </TD>
</xsl:template>

<xsl:template match="phone" mode="accountNumber">
   <TD STYLE="font-style:italic">
      1-<xsl:value-of select="."/>-001
   </TD>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

<HTML>
<BODY>
<TABLE border="1" cellspacing="0" cellpadding="2">
<TR>
<TD STYLE="font-size:14pt font-family:serif">Peter Furst</TD>
<TD>456 Pine Av.</TD>
<TD>CA</TD>
<TD>(209) 765-4321</TD>
<TD STYLE="font-style:italic">
      1-(209) 765-4321-001
   </TD>
</TR>
<TR>
<TD STYLE="font-size:14pt font-family:serif">Dan Russell</TD>
<TD>9876 Main St.</TD>
...
</TR>
</TABLE>
</BODY>
</HTML>


xsl:attribute Element

Creates an attribute node and attaches it to an output element.

<xsl:attribute
  name = "attribute-name"
  namespace = "uri-reference">
</xsl:attribute>

Attributes

name
Required. Name of the attribute to create. If this value is a QName, the attribute node is created in the namespace currently bound to the prefix unless otherwise overridden by the presence of a namespace attribute. The value of the name attribute is interpreted as an attribute value template (expressions in curly braces are evaluated and converted to strings as in <xsl:value-of>). This allows the name of the attribute to be calculated or obtained from the source XML.
namespace
The namespace Uniform Resource Identifier (URI) of the created attribute. If the name attribute contains a QName, the prefix specified there will be bound to the namespace specified in the namespace attribute, possibly resulting in the addition of other namespace declarations when serializing. This value is interpreted as an attribute value template.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:template, xsl:variable, xsl:when, xsl:with-param
Child elements | xsl:apply-imports, xsl:apply-templates, xsl:call-template, xsl:choose, xsl:copy, xsl:copy-of, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:number, xsl:text, xsl:value-of, xsl:variable

Remarks

The contents of this element specify the value of the attribute.

Attributes can be added or modified during transformation by placing the <xsl:attribute> element within elements that generate output, such as the <xsl:copy> element. Note that <xsl:attribute> can be used directly on output elements and not only in conjunction with <xsl:element>.

All attributes must be applied before children are added to the element.

Short Example

This example generates an attribute that obtains its value from the XML source. It generates output in the form <IMG src="value-from-XML-source"/>, using an XPath expression that retrieves the appropriate data from the XML source — here, "imagenames/imagename".

<IMG>
  <xsl:attribute name="src">
    <xsl:value-of select="imagenames/imagename" />
  </xsl:attribute>
</IMG>

As with an xsl:element element, the xsl:attribute element can be extremely useful for dynamically creating output attributes that are not known at transform. In the example above, you might already know that an IMG element must contain a src attribute. Because this requirement is known prior to transform, you would not have to use the xsl:attribute element to first create and associate an attribute and then dynamically populate its value. You could simplify the transformation syntax and still achieve the same result by using the following:

<IMG src="{imagenames/imagename}"/>

The reasons for using xsl:attribute instead of attribute value templates are:

  • The name of the attribute can be calculated.
  • Conditionals, templates and attribute set can be used in conjunction with attribute generation.
  • Adding attributes to an element generated with xsl:copy or xsl:element.

Full Examples

Example 1 for <xsl:attribute>

Example 2 for <xsl:attribute>

Example 3 for <xsl:attribute>

See Also

Selecting and Outputting Attributes | Generating Comments, Processing Instructions, and Elements | Qualified Names


Example 1 for <xsl:attribute>

This example copies the "myElement" element and adds a "copied" attribute with the value "true".

XML File (myelem.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="attrcopied.xsl" ?>
<root>
   <myElement>My Data</myElement>
   <myElement>My Other Data</myElement>
</root>

XSLT File (attrcopied.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:template match="myElement">
  <xsl:copy>
    <xsl:attribute name="copied">true</xsl:attribute>
    <xsl:apply-templates />
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Formatted Output

My DataMy Other Data

Processor Output

Line breaks are added for clarity.

<?xml version="1.0" encoding="UTF-16"?>
<myElement copied="true">My Data</myElement>
<myElement copied="true">My Other Data</myElement>


Example 2 for <xsl:attribute>

This example demonstrates how to use attribute value templates to use content in the XML source document as the name of an attribute.

XML File (attribute.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="attribute.xsl"?>
<investment>
   <type>stock</type>
   <name>Microsoft</name>
   <price type="high">100</price>
   <price type="low">94</price>
</investment>

XSLT File (attribute.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" indent="yes"/>

<xsl:template match="investment">
   <xsl:element name="{type}">
      <xsl:attribute name="name" >
         <xsl:value-of select="name"/>
      </xsl:attribute>
      <xsl:for-each select="price">
      <xsl:attribute name="{@type}" >
         <xsl:value-of select="."/>
      </xsl:attribute>
      </xsl:for-each>
   </xsl:element>
</xsl:template>

</xsl:stylesheet>

Formatted Output

None; a blank page appears in Internet Explorer.

Processor Output

<?xml version="1.0" encoding="UTF-16"?>
<stock name="Microsoft" high="100" low="94">
</stock>


Example 3 for <xsl:attribute>

This example shows the use of <xsl:attribute name="{name()}"/>.

XML File (attribute.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="attribute.xsl"?>
<root>
   <bar>bar1</bar>
   <bar>bar2</bar>
   <bar>bar3</bar>
   <bar>bar4</bar>
   <bar>bar5</bar>
</root>

XSLT File (attribute.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" indent="yes"/>

<xsl:template match="//bar">
   <xsl:element name="foobar">
      <xsl:attribute name="{name()}">
         <xsl:value-of select="."/>
      </xsl:attribute>
   </xsl:element>
</xsl:template>

</xsl:stylesheet>

Formatted Output

None; a blank page appears in Internet Explorer.

Processor Output

<?xml version="1.0" encoding="UTF-16"?>
<foobar bar="bar1" />
<foobar bar="bar2" />
...
<foobar bar="bar5" />


xsl:attribute-set Element

Defines a named set of attributes.

<xsl:attribute-set
  name = qname
  use-attribute-sets = qnames>
</xsl:attribute-set>

Attributes

name
Required. Name of the attribute set.
use-attribute-sets
A white space-separated list of attribute sets specified as a qualified name. Specifying a use-attribute-sets attribute is equivalent to adding <xsl:attribute> elements for each of the attributes in each of the named attribute sets to the beginning of the content of the element with the use-attribute-sets attribute, in the same order in which the names of the attribute sets are specified in the use-attribute-sets attribute. It is an error if using use-attribute-sets attributes on <xsl:attribute-set> elements causes an attribute set to directly or indirectly use itself.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:stylesheet, xsl:transform
Child elements | xsl:attribute

Remarks

The <xsl:attribute-set> element defines a named set of attributes. The name attribute specifies the name of the attribute set. The value of the name attribute is a qualified name. The content of the <xsl:attribute-set> element consists of zero or more <xsl:attribute> elements that specify the attributes in the set.

Attribute sets are used by specifying a use-attribute-sets attribute on <xsl:element>, <xsl:copy>, or <xsl:attribute-set> elements. The value of the use-attribute-sets attribute is a white space-separated list of names of attribute sets. Each name is specified as a qualified name. Specifying a use-attribute-sets attribute is equivalent to adding <xsl:attribute> elements for each of the attributes in each of the named attribute sets to the beginning of the content of the element with the use-attribute-sets attribute, in the same order in which the names of the attribute sets are specified in the use-attribute-sets attribute. It is an error if using use-attribute-sets attributes on <xsl:attribute-set> elements causes an attribute set to directly or indirectly use itself.

Attribute sets can also be used by specifying an xsl:use-attribute-sets attribute on a literal result element. The value of the xsl:use-attribute-sets attribute is a white space-separated list of names of attribute sets. The xsl:use-attribute-sets attribute has the same effect as the use-attribute-sets attribute on <xsl:element> with the additional rule that attributes specified on the literal result element itself are treated as if they were specified by <xsl:attribute> elements before any actual <xsl:attribute> elements but after any <xsl:attribute> elements implied by the xsl:use-attribute-sets attribute. Thus, for a literal result element, attributes from attribute sets named in an xsl:use-attribute-sets attribute will be added first, in the order listed in the attribute; next, attributes specified on the literal result element will be added; finally, any attributes specified by <xsl:attribute> elements will be added. Since adding an attribute to an element replaces any existing attribute of that element with the same name, this means that attributes specified in attribute sets can be overridden by attributes specified on the literal result element itself.

The template within each <xsl:attribute> element in an <xsl:attribute-set> element is instantiated each time the attribute set is used; it is instantiated using the same current node and current node list as is used for instantiating the element bearing the use-attribute-sets or xsl:use-attribute-sets attribute. However, it is the position in the style sheet of the <xsl:attribute> element rather than of the element bearing the use-attribute-sets or xsl:use-attribute-sets attribute that determines which variable bindings are visible; thus, only variables and parameters declared by top-level <xsl:variable> and <xsl:param> elements are visible.

Multiple definitions of an attribute set with the same expanded-name are merged. An attribute from a definition that has higher import precedence takes precedence over an attribute from a definition that has lower import precedence.

It is an error if there are two attribute sets that have the same expanded-name and equal import precedence and that both contain the same attribute, unless there is a definition of the attribute set with higher import precedence that also contains the attribute.

Example

The following example creates a named attribute set called "title-style" and uses it in a template rule.

XML File (book.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="attrset.xsl" ?>
<book>
   <chapter>
      <heading>The First Heading</heading>
   </chapter>
   <chapter>
      <heading>The Next Heading</heading>
   </chapter>
</book>

XSLT File (attrset.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl:template match="chapter/heading">
  <fo:block quadding="start" xsl:use-attribute-sets="title-style">
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:attribute-set name="title-style">
  <xsl:attribute name="font-size">12pt</xsl:attribute>
  <xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:attribute-set>

</xsl:stylesheet>

Formatted Output

The First HeadingThe Next Heading

Processor Output

Line breaks added for clarity.

<?xml version="1.0" encoding="UTF-16"?>
<fo:block font-size="12pt"
          font-weight="bold"
          quadding="start"
          xmlns:fo="http://www.w3.org/1999/XSL/Format">
The First Heading
</fo:block>
<fo:block font-size="12pt"
          font-weight="bold"
          quadding="start"
          xmlns:fo="http://www.w3.org/1999/XSL/Format">
The Next Heading
</fo:block>

See Also

xsl:attribute Element | xsl:element Element | xsl:copy Element


xsl:call-template Element

Invokes a template by name.

<xsl:call-template
  name = Qname>
</xsl:call-template>

Attributes

name
Required. Name of the template to be invoked.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:attribute, xsl:comment, xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:processing-instruction, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | xsl:with-param

Remarks

The <xsl:call-template> enables you to invoke a named template — an <xsl:template> element — with an assigned name attribute. If an <xsl:template> element has a name attribute, it may, but need not, also have a match attribute. An <xsl:call-template> element invokes a template by name; it has a required name attribute that identifies the template to be invoked. Unlike <xsl:apply-templates>, <xsl:call-template> does not change the current node or the current node-list.

An error occurs if a style sheet contains more than one template with the same name.

An <xsl:call-template> element can contain any number of <xsl:with-param> elements. However, it cannot contain other XSLT elements.

Example

The following <xsl:call-template> element:

<xsl:call-template name="foo"/>

invokes the following template rule:

<xsl:template name="foo" match="//bar">
  <xsl:value-of select="."/>
</xsl:template>

See Also

xsl:template Element | xsl:call-template example in XSLT Samples Viewer

Other Resources Other Resources

XSLT Samples Viewer


xsl:choose Element

Provides multiple conditional testing in conjunction with the <xsl:otherwise> and <xsl:when> elements.

<xsl:choose>
</xsl:choose>

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:attribute, xsl:comment, xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:processing-instruction, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | xsl:otherwise, xsl:when

Remarks

The <xsl:when> children of the <xsl:choose> element are tested in order from top to bottom until a test attribute on one of these elements accurately describes conditions present in the source data or an <xsl:otherwise> element is reached. Once an <xsl:when> or <xsl:otherwise> element is chosen, the <xsl:choose> block is exited. No explicit break or exit statement is required.

For simple conditional testing, use the <xsl:if> element.

Example

This example shows a template for "order" elements and inserts an <HR> or <BR> before the order's contents, based on the order's "total" element value. If the total is less than 10, a red <HR> will be generated; if the total is less than 20, a pink <HR> will be generated; otherwise a <BR> element will be created.

XML File (order.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="refchoose.xsl" ?>
<orders>
   <order>
      <lineitem/>
      <lineitem/>
      <total>9</total>
   </order>
   <order>
      <lineitem/>
      <lineitem/>
      <total>19</total>
   </order>
   <order>
      <lineitem/>
      <lineitem/>
      <total>29</total>
   </order>
</orders>

XSLT File (refchoose.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:template match="order">
   <xsl:choose>
      <xsl:when test="total &lt; 10">
         <HR STYLE="color:red"/>
      </xsl:when>
      <xsl:when test="total &lt; 20">
         <HR STYLE="color:pink"/>
      </xsl:when>
      <xsl:otherwise>
         <BR/>
      </xsl:otherwise>
   </xsl:choose>
   <xsl:apply-templates />
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

Line breaks added for clarity.

<?xml version="1.0" encoding="UTF-16"?>
<HR STYLE="color:red" />9
<HR STYLE="color:pink" />19
<BR />29

See Also

Defining Conditional Templates Using <xsl:if> and <xsl:choose>


xsl:comment Element

Generates a comment in the output.

<xsl:comment>
</xsl:comment>

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | xsl:apply-imports, xsl:apply-templates, xsl:call-template, xsl:choose, xsl:copy, xsl:copy-of, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:number, xsl:text, xsl:value-of, xsl:variable

Remarks

The text generated by the children of <xsl:comment> appears between the starting characters <!-- and the closing characters -->.

Example

In the following example, the news.xsl stylesheet transforms the news.xml document and inserts a comment into the XSLT output.

XML File (news.xml)

<?xml version ="1.0"?>
<?xml-stylesheet type="text/xsl" href="news.xsl"?>
<news>
<story1>Here is the top news story.</story1>
    <story2> Here is the next news story.</story2>
</news>

XSLT File (news.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:template match="/">
<HTML>
<BODY>
<xsl:comment>insert top news story</xsl:comment>
<P>
<xsl:value-of select="//story1"/>
</P>
</BODY>
</HTML>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Here is the top news story.

Processor Output

<HTML>
<BODY>
<!--insert top news story-->
<P>Here is the top news story.</P>
</BODY>
</HTML>

See Also

Generating Comments, Processing Instructions, and Elements

Other Resources Other Resources

Internet Explorer Tools for Validating XML and Viewing XSLT Output


xsl:copy Element

Copies the current node from the source to the output.

<xsl:copy
  use-attribute-sets = QName>
</xsl:copy>

Attributes

use-attribute-sets
A white space-separated list of attribute sets specified as a qualified name. Specifying a use-attribute-sets attribute is equivalent to adding <xsl:attribute> elements for each of the attributes in each of the named attribute sets to the beginning of the content of the element with the use-attribute-sets attribute, in the same order in which the names of the attribute sets are specified in the use-attribute-sets attribute. It is an error if use of use-attribute-sets attributes on <xsl:attribute-set> elements causes an attribute set to directly or indirectly use itself.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:attribute, xsl:comment, xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:processing-instruction, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | xsl:apply-templates, xsl:attribute, xsl:call-template, xsl:choose, xsl:comment, xsl:copy, xsl:copy-of, xsl:element, xsl:for-each, xsl:if, xsl:processing-instruction, xsl:text, xsl:value-of, xsl:variable, output elements

Remarks

The <xsl:copy> element creates a node in the output with the same name, namespace, and type as the current node. Attributes and children are not copied automatically. This element makes identity transformation possible.

Example

The following example performs an identity transform on the entire document. The identity transform copies each node in the source to the output to provide a logically equivalent tree. It does not yield character-by-character equivalence — entities will be expanded and white space not marked as significant may be removed.

XML File (booksshort.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="identityxfm.xsl"?>
<catalog>
    <book id="bk101">
        <author>Gambardella, Matthew</author>
        <title>XML Developer's Guide</title>
        <genre>Computer</genre>
        <price>44.95</price>
        <publish_date>2000-10-01</publish_date>
        <description>An in-depth look at creating applications with
 XML.</description>
    </book>
    <book id="bk102">
        <author>Ralls, Kim</author>
        <title>Midnight Rain</title>
        <genre>Fantasy</genre>
        <price>5.95</price>
        <publish_date>2000-12-16</publish_date>
        <description>A former architect battles corporate zombies,
 an evil sorceress, and her own childhood to become queen of the
 world.</description>
    </book>
    <book id="bk103">
        <author>Corets, Eva</author>
        <title>Maeve Ascendant</title>
        <genre>Fantasy</genre>
        <price>5.95</price>
        <publish_date>2000-11-17</publish_date>
        <description>After the collapse of a nanotechnology society
 in England, the young survivors lay the foundation for a new
society.</description>
    </book>
</catalog>

XSLT File (identityxfm.xsl)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

  <xsl:template match="/ | @* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Formatted Output

A portion of the display is shown here, truncated on the right side.

Gambardella, MatthewComputer44.952000-10-01An in-depth look
and her own childhood to become queen of the world.Corets, EvaFa

Processor Output

<?xml version="1.0" encoding="UTF-16"?><?xml-stylesheet type="text/xsl"
href="identityxfm.xsl"?><catalog><book id="bk101"><author>Gambardella,
Matthew</author><title>XML Developer's
Guide</title><genre>Computer</genre><price>44.95</price><publish_date>2000
-10-01</publish_date><description>An in-depth look at creating
applications with
 XML.</description></book><book id="bk102">
...
</book></catalog>

See Also

Generating Comments, Processing Instructions, and Elements


xsl:copy-of Element

Inserts subtrees and result-tree fragments into the result tree.

<xsl:copy-of
  select = expression/>

Attributes

select
Required. XPath expression identifying nodes to be copied. The subtree below each of these nodes is copied to the result tree in its entirety.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:attribute, xsl:comment, xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:processing-instruction, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | (No child elements)

Remarks

When the result of evaluating the expression is a result-tree fragment, the complete fragment is copied into the result tree. When the result is a node-set, all the nodes in the set are copied in document order into the result tree; copying an element node copies the attribute nodes, namespace nodes, and children of the element node as well as the element node itself. A root node is copied by copying its children. When the result is neither a node-set nor a result-tree fragment, the result is converted to a string and then inserted into the result tree, as with <xsl:value-of>.

Example

This sample XSLT file operates against the sample XML file to find a person element with "given-name" and "family-name" children elements. The paragraph will contain the first "given-name" child element of the current node, including any attributes and child elements, followed by a space and the first "family-name" child element, including any attributes and child elements, of the current node.

XML File (family.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="family.xsl"?>
<family>
  <person>
    <given-name age="10">
      <name>Fred</name>
      <nick-name>Freddy</nick-name>
    </given-name>
    <family-name>Smith</family-name>
  </person>
  <person>
    <given-name age="10">
      <name>Robert</name>
      <nick-name>Bob</nick-name>
    </given-name>
    <family-name>Smith</family-name>
  </person>
</family>

XSLT File (family.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:template match="person">
  <p>
    <xsl:copy-of select="given-name"/>
    <xsl:text> </xsl:text>
    <xsl:copy-of select="family-name"/>
  </p>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Fred Freddy Smith
Robert Bob Smith

Processor Output

Some line breaks added for clarity.

<?xml version="1.0" encoding="UTF-16"?>
<p><given-name age="10">
<name>Fred</name>
<nick-name>Freddy</nick-name>
</given-name>
<family-name>Smith</family-name></p>
<p><given-name age="10">
<name>Robert</name>
<nick-name>Bob</nick-name>
</given-name>
<family-name>Smith</family-name></p>

See Also

xsl:value-of Element


xsl:decimal-format Element

Declares a decimal-format, which controls the interpretation of a format pattern used by the format-number function. If there is a name attribute, then the element declares a named decimal-format; otherwise, it declares the default decimal-format. The value of the name attribute is a qualified name (QName). It is an error to declare either the default decimal-format or a decimal-format with a given name more than once (even with different import precedence), unless it is declared every time with the same value for all attributes (taking into account any default values). For more information, see format-number Function.

<xsl:decimal-format
  name = qname
  decimal-separator = char
  grouping-separator = char
  infinity = string
  minus-sign = char
  NaN = string
  percent = char
  per-mille = char
  zero-digit = char
  digit = char
  pattern-separator = char />

Attributes

name
Optional. The name of the decimal format. If there is a name attribute, then the element declares a named decimal-format; otherwise, it declares the default decimal-format. The value of the name attribute is a qualified name. It is an error to declare either the default decimal-format or a decimal-format with a given name more than once unless it is declared every time with the same value for all attributes (taking into account any default values).
decimal-separator
Optional. The character used to separate the integer and the fraction part of a number. The default is ".".
grouping-separator
Optional. The character used to separate groups of digits. The default is ",".
infinity
Optional. The string used to represent infinity; the default value is the string Infinity.
minus-sign
Optional. The character used as the default minus sign; the default value is the hyphen-minus character (-, #x2D).
NaN
Optional. The string used to represent the NaN value; the default value is the string NaN.
percent
Optional. The character used as a percent sign; the default value is the percent character (%).
per-mille
Optional. The character used as a per mille (per thousand) sign; the default value is the Unicode per-mille character (#x2030).
zero-digit
Optional. The character used as the digit zero; the default value is the digit zero (0).
digit
Optional. The character used in a format pattern to indicate a place where a leading zero digit is required. The default value is "#".
pattern-separator
Optional. The character used to separate positive and negative sub patterns in a pattern; the default value is the semi-colon character (;), as shown here:
format-number(-123.45, '###,###.00;(###,###.00)')

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:stylesheet, xsl:transform
Child elements | (No child elements)

Example

This example demonstrates number formatting using the xsl:decimal-format element.

XML File (root.xml)

You can view this file or the XSLT file in Internet Explorer; the XSLT file calls itself.

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="decimalformat.xsl" ?>
<root/>

XSLT File (decimalformat.xsl)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="decimalformat.xsl"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:output method="html"/>
<xsl:decimal-format name="us" decimal-separator='.' grouping-separator=',' />
<xsl:decimal-format name="european" decimal-separator=',' grouping-separator='.' />
<xsl:decimal-format name="example" decimal-separator="." grouping-separator=","
   infinity="INFINITY" minus-sign="-" NaN="Not a Number" percent="%"
   per-mille="m" zero-digit="0" digit="#" pattern-separator=";" />

<xsl:template match="/">
<HTML><BODY>
<table border="1" cellpadding="2" cellspacing="0">
<tr align="center">
   <td><b>Data</b></td>
   <td><b>Default</b></td>
   <td><b>European</b></td>
   <td><b>US</b></td>
   <td><b>Example</b></td>
</tr>
<tr align="right">
   <td>24535.2</td>
   <td><xsl:value-of select="format-number(24535.2, '###,###.00')"/></td>
   <td><xsl:value-of select="format-number(24535.2, '###.###,00', 'european')"/></td>
   <td><xsl:value-of select="format-number(24535.2, '###,###.00', 'us')"/></td>
   <td><xsl:value-of select="format-number(24535.2, '###,###.00', 'example')"/></td>
</tr>
<tr align="right">
   <td>-123.45</td>
   <td><xsl:value-of select="format-number(-123.45, '###,###.00')"/></td>
   <td><xsl:value-of select="format-number(-123.45, '###.###,00', 'european')"/></td>
   <td><xsl:value-of select="format-number(-123.45, '###,###.00', 'us')"/></td>
   <td><xsl:value-of select="format-number(-123.45, '###,###.00', 'example')"/></td>
</tr>
<tr align="right">
   <td>-123.45</td>
   <td><xsl:value-of select="format-number(-123.45, '###,###.00;(###,###.00)')"/></td>
   <td><xsl:value-of select="format-number(-123.45, '###.###,00;(###.###,00)', 'european')"/></td>
   <td><xsl:value-of select="format-number(-123.45, '###,###.00;(###,###.00)', 'us')"/></td>
   <td><xsl:value-of select="format-number(-123.45, '###,###.00;(###,###.00)', 'example')"/></td>
</tr>
<tr align="right">
   <td>193 div 200</td>
   <td><xsl:value-of select="format-number(193 div 200, '###.#%')"/></td>
   <td><xsl:value-of select="format-number(193 div 200, '###,#%', 'european')"/></td>
   <td><xsl:value-of select="format-number(193 div 200, '###.#%', 'us')"/></td>
   <td><xsl:value-of select="format-number(193 div 200, '###.#%', 'example')"/></td>
</tr>
<tr align="right">
   <td>193 div 200</td>
   <td><xsl:value-of select="format-number(193 div 200, '###.#&#x2030;')"/></td>
   <td><xsl:value-of select="format-number(193 div 200, '###,#&#x2030;', 'european')"/></td>
   <td><xsl:value-of select="format-number(193 div 200, '###.#&#x2030;', 'us')"/></td>
   <td><xsl:value-of select="format-number(193 div 200, '###.#m', 'example')"/></td>
</tr>
<tr align="right">
   <td>1 div 0</td>
   <td><xsl:value-of select="format-number(1 div 0, '###,###.00')"/></td>
   <td><xsl:value-of select="format-number(1 div 0, '###.###,00', 'european')"/></td>
   <td><xsl:value-of select="format-number(1 div 0, '###,###.00', 'us')"/></td>
   <td><xsl:value-of select="format-number(1 div 0, '###,###.00', 'example')"/></td>
</tr>
<tr align="right">
   <td>a div 0</td>
   <td><xsl:value-of select="format-number(a div 0, '###,###.00')"/></td>
   <td><xsl:value-of select="format-number(a div 0, '###.###,00', 'european')"/></td>
   <td><xsl:value-of select="format-number(a div 0, '###,###.00', 'us')"/></td>
   <td><xsl:value-of select="format-number(a div 0, '###,###.00', 'example')"/></td>
</tr>
</table>
</BODY></HTML>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

A portion of the output stream is shown here.

<HTML><BODY>
<table border="1" cellpadding="2" cellspacing="0">
<tr align="center">
<td><b>Data</b></td>
<td><b>Default</b></td>
<td><b>European</b></td>
<td><b>US</b></td>
<td><b>Example</b></td>
</tr>
<tr align="right">
<td>24535.2</td>
<td>24,535.20</td>
<td>24.535,20</td>
<td>24,535.20</td>
<td>24,535.20</td>
</tr>
<tr align="right">
<td>1 div 0</td>
<td>Infinity</td>
<td>Infinity</td>
<td>Infinity</td>
<td>INFINITY</td>
</tr>
</table>
</BODY></HTML>

See Also

format-number Function | Qualified Names


xsl:element Element

Creates an element with the specified name in the output.

<xsl:element
  name = "element-name"
  namespace = "uri-reference"
  use-attribute-sets = QName
</xsl:element>

Attributes

name
Required. Name of the element to create. If this value is a qualified name (QName), the element node is created in the namespace currently bound to the prefix unless otherwise overridden by the presence of a namespace attribute. The value of the name attribute is interpreted as an attribute value template (expressions in curly braces are evaluated and converted to strings as in <xsl:value-of>). This allows the name of the element to be calculated or obtained from the source XML.
namespace
The namespace URI of the created element. If the name element contains a QName, the prefix specified there will be bound to the namespace specified in the namespace attribute, possibly resulting in the addition of additional namespace declarations when serializing. This value is interpreted as an attribute value template.
use-attribute-sets
A white space-separated list of attribute sets specified as a qualified name. Specifying a use-attribute-sets attribute is equivalent to adding <xsl:attribute> elements for each of the attributes in each of the named attribute sets to the beginning of the content of the element with the use-attribute-sets attribute, in the same order in which the names of the attribute sets are specified in the use-attribute-sets attribute. It is an error if use of use-attribute-sets attributes on <xsl:attribute-set> elements causes an attribute set to directly or indirectly use itself.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | xsl:apply-templates, xsl:attribute, xsl:call-template, xsl:choose, xsl:comment, xsl:copy, xsl:copy-of, xsl:element, xsl:for-each, xsl:if, xsl:processing-instruction, xsl:text, xsl:value-of, xsl:variable, output elements

Remarks

The <xsl:element> element allows an element to be created with a computed name. The name of the element to be created is specified by a required name attribute and an optional namespace attribute. The content of the <xsl:element> element is a template for the attributes and children of the created element.

This element provides an escaping mechanism for creating elements with namespace clashes, such as XSLT itself.

Example

The <xsl:element> element is necessary because XSLT elements cannot be used as output elements. This example shows how to output an <xsl:template ...> element.

XML File (item.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="element.xsl" ?>
<root>
   <item>My Item</item>
</root>

XSLT File (element.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:template match="item">
   <xsl:element name="xsl:template">
      <xsl:attribute name="match">cost</xsl:attribute>
      <xsl:attribute name="xml:space">preserve</xsl:attribute>
      <xsl:apply-templates/>
   </xsl:element>
</xsl:template>

</xsl:stylesheet>

Formatted Output

My Item

Processor Output

Line breaks added for clarity.

<?xml version="1.0" encoding="UTF-16"?>
<xsl:template match="cost"
      xml:space="preserve"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
My Item</xsl:template>

See Also

Generating Comments, Processing Instructions, and Elements | Qualified Names


xsl:fallback Element

The <xsl:fallback> element is designed to handle situations where the parser cannot handle an XSL element that may be part of a new version, or is otherwise an unrecognized extension. It works by calling template content that can provide a reasonable substitute to the behavior of the new element when encountered.

<xsl:fallback>
</xsl:fallback>

Attributes

None

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:attribute, xsl:comment, xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:processing-instruction, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | xsl:apply-templates, xsl:attribute, xsl:call-template, xsl:choose, xsl:comment, xsl:copy, xsl:copy-of, xsl:element, xsl:for-each, xsl:if, xsl:processing-instruction, xsl:text, xsl:value-of, xsl:variable, output elements

Remarks

When an XSL document is first loaded, the XSLT preparser performs validation on all XSL elements. If the version passed in the <xsl:stylesheet> element is greater than that supported by the parser, then whenever an unfamiliar element is encountered, the parser will execute the <xsl:fallback> children of that element (or simply not perform any action if the fallback has no content). If the element is supported, then the fallback templates are never instantiated. Likewise, if the version given in the style sheet is the same as that supported by the browser, then an error will be called.

Fallbacks are part of the forward-processing mechanism that XSLT uses for handling upgrades. By creating alternative ways of handling a command if an element is not supported, forward-processing guarantees that the code used is relatively robust and insensitive to differences in parser conformity.

In addition to handling versioning differences, the fallback function can also be used to handle elements defined by namespace extensions. Because adding functionality to the base specification is typically very difficult, namespace extensions let developers define functionality beyond that specified by the XSLT specification. If the namespace is not supported (no definition for the namespace is provided), or if a namespace function or element is not defined, then the fallback mechanism can be used to provide alternate functionality.

To guarantee that the extension is interpreted within the XSLT operation, you need to set the extension-element-prefixes attribute in the <xsl:stylesheet> element so that it contains the name of the prefix to interpret. In addition, declare the namespace for that prefix.

Example

The fallback.xsl style sheet provides alternate processing for an XML document. The fallback.xsl style sheet attempts to process the XML document with a hypothetical <xsl:import-table> element. Because this element is not supported in the current version of the parser, the document is alternately processed with the script inside the fallback element.

XML File (records.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="fallback.xsl"?>
<records>
    <record>
        <name>Adam Barr</name>
        <address>222 Cherry</address>
        <phone>555-797-2355</phone>
    </record>
    <record>
        <name>Jeff Adell</name>
        <address>730 Elm</address>
        <phone>555-797-5555</phone>
    </record>
</records>

XSLT File (fallback.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.1"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

  <xsl:template match="/">
     <HTML>
     <HEAD><TITLE>Output Table</TITLE></HEAD>
     <BODY>
     <xsl:import-table href="blah.html" name="sample">
        <xsl:fallback>
        <p>This version of the parser does not support the creation of a table with the 'xsl:import-table' element, so the following table has been generated using the 'fallback' element.</p>
          <table border='2'>
            <xsl:for-each select='records/record'>
              <tr>
                <td><xsl:value-of select='name'/></td>
                <td><xsl:value-of select='address'/></td>
                <td><xsl:value-of select='phone'/></td>
              </tr>
            </xsl:for-each>
          </table>
        </xsl:fallback>
      </xsl:import-table>
      </BODY>
    </HTML>
  </xsl:template>

</xsl:stylesheet>

Formatted Output

In this scenario, the current version of the parser does not support the creation of a table with the xsl:import-table element, so the following table is generated using the fallback element:

Adam Barr | 222 Cherry | 555-797-2355
Jeff Adell | 730 Elm | 555-797-5555

See Also

system-property Function | element-available Function | function-available Function


xsl:for-each Element

Applies a template repeatedly, applying it in turn to each node in a set.

<xsl:for-each
  select = expression>
</xsl:for-each>

Attributes

select
Required. Expression evaluated on the current context to determine the set of nodes to iterate over.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:attribute, xsl:comment, xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:processing-instruction, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | xsl:apply-imports, xsl:apply-templates, xsl:attribute, xsl:call-template, xsl:choose, xsl:comment, xsl:copy, xsl:copy-of, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:number, xsl:processing-instruction, xsl:sort, xsl:text, xsl:value-of, xsl:variable, output elements

Remarks

The <xsl:for-each> element establishes the context for iteration; the XSLT transformation instructions within this loop are to be applied to the selected nodes. Each source element selected by <xsl:for-each> becomes a new context against which any pattern matching within the <xsl:for-each> occurs.

Example

This example specifies a template that defines what the structure of the overall output document should be (a top-level HTML element containing <BODY> and <TABLE> elements with repeated rows for each customer) and uses templates to create <TD> elements for the name, address, and phone source elements.

XML File (customers.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="foreach.xsl" ?>
<customers>
   <customer>
      <name>John Smith</name>
      <address>123 Oak St.</address>
      <state>WA</state>
      <phone>(206) 123-4567</phone>
   </customer>
   <customer>
      <name>Zack Zwyker</name>
      <address>368 Elm St.</address>
      <state>WA</state>
      <phone>(206) 423-4537</phone>
   </customer>
   <customer>
      <name>Albert Aikens</name>
      <address>368 Elm St.</address>
      <state>WA</state>
      <phone>(206) 423-4537</phone>
   </customer>
   <customer>
      <name>Albert Gandy</name>
      <address>6984 4th St.</address>
      <state>WA</state>
      <phone>(206) 433-4547</phone>
   </customer>
   <customer>
      <name>Peter Furst</name>
      <address>456 Pine Av.</address>
      <state>CA</state>
      <phone>(209) 765-4321</phone>
   </customer>
   <customer>
      <name>Dan Russell</name>
      <address>9876 Main St.</address>
      <state>PA</state>
      <phone>(323) 321-7654</phone>
   </customer>
</customers>

XSLT File (foreach.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

  <xsl:template match="/">
    <HTML>
      <BODY>
        <TABLE>
          <xsl:for-each select="customers/customer">
            <xsl:sort select="state" order="descending"/>
            <xsl:sort select="name"/>
            <TR>
              <TD><xsl:value-of select="name" /></TD>
              <TD><xsl:value-of select="address" /></TD>
              <TD><xsl:value-of select="phone" /></TD>
            </TR>
          </xsl:for-each>
        </TABLE>
      </BODY>
    </HTML>
  </xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

<HTML>
<BODY>
<TABLE>
<TR>
<TD>Albert Aikens</TD>
<TD>368 Elm St.</TD>
<TD>(206) 423-4537</TD>
</TR>
<TR>
<TD>Albert Gandy</TD>
...
</TR>
</TABLE>
</BODY>
</HTML>

See Also

Creating and Populating an HTML Template


xsl:if Element

Allows simple conditional template fragments.

<xsl:if
  test = boolean expression>
</xsl:if>

Attributes

test
Required. The condition in the source data to test. If the expression in this attribute evaluates to true when cast to a Boolean, the content of <xsl:if> is instantiated and placed in the output. Node-sets are cast to a Boolean True if they contain at least one node.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:attribute, xsl:comment, xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:processing-instruction, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | xsl:apply-templates, xsl:attribute, xsl:call-template, xsl:choose, xsl:comment, xsl:copy, xsl:copy-of, xsl:element, xsl:for-each, xsl:if, xsl:processing-instruction, xsl:text, xsl:value-of, xsl:variable, output elements

Remarks

The content is a template. The expression is evaluated, and the resulting object is converted to a Boolean. If the result is True, the content template is instantiated; otherwise, nothing is created.

Examples

  • Example 1 of <xsl:if>
  • Example 2 of <xsl:if>
  • Example 3 of <xsl:if>
  • Example 4 of <xsl:if>

See Also

Defining Conditional Templates Using <xsl:if> and <xsl:choose>


Example 1 of <xsl:if>

In this example, the names in a group of names are formatted as a comma-separated list.

XML File (names.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="ifcomma.xsl" ?>
<namelist>
   <name>Albert</name>
   <name>Terrance</name>
   <name>Will</name>
   <name>Sylvia</name>
   <name>Timothy</name>
   <name>Gordon</name>
   <name>James</name>
   <name>Robert</name>
   <name>Dan</name>
   <name>Sasha</name>
</namelist>

XSLT File (ifcomma.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:template match="namelist/name">
  <xsl:apply-templates/>
  <xsl:if test="position()!=last()">, </xsl:if>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Albert, Terrance, Will, Sylvia, Timothy, Gordon, James, Robert, Dan, Sasha

Processor Output

<?xml version="1.0" encoding="UTF-16"?>Albert, Terrance, Will, Sylvia, Timothy, Gordon, James, Robert, Dan, Sasha


Example 2 of <xsl:if>

Another way to separate the names by commas is by reversing the logic to do a check if this name is the first. In some circumstances this performs better than the above example since last() requires that the entire set of names be found and counted, while this approach does not.

XML File (names.xml)

Use the names.xml listing above, but edit the href attribute to point to ifcomma2.xsl.

XSLT File (ifcomma2.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:template match="namelist/name">
  <xsl:if test="position()!=1">, </xsl:if>
  <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Albert, Terrance, Will, Sylvia, Timothy, Gordon, James, Robert, Dan, Sasha

Processor Output

<?xml version="1.0" encoding="UTF-16"?>Albert, Terrance, Will, Sylvia, Timothy, Gordon, James, Robert, Dan, Sasha


Example 3 of <xsl:if>

The following item template rule colors every other table row yellow.

XML File (items.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="ifyellow.xsl" ?>
<items>
   <item>Car</item>
   <item>Pen</item>
   <item>LP Record</item>
   <item>Wisdom</item>
   <item>Cell phone</item>
   <item>Film projector</item>
   <item>Hole</item>
   <item>Canopy</item>
   <item>Widget</item>
   <item>Concept</item>
   <item>Null character</item>
</items>

XSLT File (ifyellow.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:template match="/">
<html>
<body>
<table border="1" cellpadding="2" cellspacing="0" width="50%">
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>

<xsl:template match="item">
  <tr>
    <xsl:if test="position() mod 2 = 0">
       <xsl:attribute name="bgcolor">yellow</xsl:attribute>
    </xsl:if>
    <xsl:apply-templates/>
  </tr>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

<html>
<body>
<table border="1" cellpadding="2" cellspacing="0" width="50%">
<tr>Car</tr>
<tr bgcolor="yellow">Pen</tr>
<tr>LP Record</tr>
<tr bgcolor="yellow">Wisdom</tr>
<tr>Cell phone</tr>
...
</table>
</body>
</html>


Example 4 of <xsl:if>

This example inserts the text "International Stock " when the stock element has an attribute named international.

XML File (stock.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="ifstock.xsl" ?>
<stocks>
   <stock international="yes">Microsoft</stock>
   <stock>Hotmail</stock>
   <stock international="yes">GM</stock>
   <stock>Smith Inc.</stock>
   <stock international="yes">Acme</stock>
</stocks>

XSLT File (ifstock.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:template match="/">
   <html><body>
   <xsl:apply-templates/>
   </body></html>
</xsl:template>

<xsl:template match="stock">
   <p/>
   <xsl:if test="@international">International Stock </xsl:if>
   <xsl:apply-templates />
</xsl:template>

</xsl:stylesheet>

Formatted Output

International Stock Microsoft

Hotmail

International Stock GM

Smith Inc.

International Stock Acme

Processor Output

Line breaks added for clarity.

<html><body>
<p></p>International Stock Microsoft
<p></p>Hotmail
<p>
...
</p>International Stock Acme
</body></html>


xsl:import Element

Imports another XSL Transformations (XSLT) style sheet.

<xsl:import
  href = uri-reference />

Attributes

href
Required. This is a Uniform Resource Identifier (URI) reference identifying the style sheet to be imported.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:stylesheet, xsl:transform
Child elements | (No child elements)

Remarks

An XSLT style sheet can import another XSLT style sheet using an <xsl:import> element. Importing a style sheet is the same as including it except that definitions and template rules in the importing style sheet take precedence over those in the imported style sheet. The <xsl:import> element has an href attribute whose value is a URI reference identifying the style sheet to be imported. A relative URI is resolved relative to the base URI of the <xsl:import> element.

The <xsl:import> element is allowed only as a top-level element. The <xsl:import> element children must precede all other element children of an <xsl:stylesheet> element, including any <xsl:include> element children. When <xsl:include> is used to include a style sheet, any <xsl:import> elements in the included document are moved up in the included document to follow any existing <xsl:import> elements in the included document.

The <xsl:stylesheet> elements encountered during processing of a style sheet that contains <xsl:import> elements are treated as forming an import tree. In the import tree, each <xsl:stylesheet> element has one import child for each <xsl:import> element that it contains. Any <xsl:include> elements are resolved before constructing the import tree. An xsl:stylesheet element in the import tree is defined to have lower import precedence than another <xsl:stylesheet> element in the import tree if it would be visited before that <xsl:stylesheet> element in a post-order traversal of the import tree (that is, a traversal of the import tree in which an <xsl:stylesheet> element is visited after its import children). Each definition and template rule has import precedence determined by the <xsl:stylesheet> element that contains it.

For example, assume the following conditions are true.

  • Style sheet A imports style sheets B and C, in that order.
  • Style sheet B imports style sheet D.
  • Style sheet C imports style sheet E.

The order of import precedence (lowest first) is D, B, E, C, A.

Note Because <xsl:import> elements are required to occur before any definitions or template rules, an implementation that processes imported style sheets at the point at which it encounters the <xsl:import> element will encounter definitions and template rules in increasing order of import precedence.

In general, a definition or template rule with higher import precedence takes precedence over a definition or template rule with lower import precedence. This is defined in detail for each kind of definition and for template rules.

It is an error if a style sheet directly or indirectly imports itself. Apart from this, the case where a style sheet with a particular URI is imported in multiple places is not treated specially. The import tree will have a separate <xsl:stylesheet> element for each place that it is imported.

Note If <xsl:apply-imports> is used, the behavior may be different from the behavior if the style sheet had been imported only at the place with the highest import precedence.

Example

For a complete working example, see Finished Example for Importing and Including or xsl:include Element.

XSLT File (importer.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:import href="article.xsl"/>
<xsl:import href="bigfont.xsl"/>

<xsl:attribute-set name="note-style">
   <xsl:attribute name="font-style">italic</xsl:attribute>
</xsl:attribute-set>

</xsl:stylesheet>

See Also

xsl:include Element | xsl:apply-imports Element | Importing and Including Style Sheets


xsl:include Element

Specifies an XSL Transformation (XSLT) style sheet to include.

<xsl:include
  href = "URI reference"/>

Attributes

href
Required. A Uniform Resource Identifier (URI) reference identifying the style sheet to be included.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:stylesheet, xsl:transform
Child elements | (No child elements)

Remarks

An XSLT style sheet can include another XSLT style sheet using the <xsl:include> element. The href attribute value is a URI reference identifying the style sheet to be included. The relative URI is resolved with relation to the base URI of the <xsl:include> element.

The <xsl:include> element is only allowed as the child of the <xsl:stylesheet> element.

Inclusions are processed in the Microsoft® XML Parser (MSXML) as if they occurred at the tree level. Note that this is not the same as the Document Object Model (DOM) view of the XML tree. The resource located by the href attribute value is parsed as an XML document, and the children of the <xsl:stylesheet> element in this document replace the <xsl:include> element in the including document. The fact that template rules or definitions are included does not affect the way they are processed.

An error occurs if a style sheet directly or indirectly includes itself.

Including a style sheet multiple times can cause errors because of duplicate definitions. Such multiple inclusions are less obvious when they are indirect. For example, if style sheet B includes style sheet A, style sheet C includes style sheet A, and style sheet D includes both style sheet B and style sheet C, then A will be included indirectly by D twice. If all of B, C, and D is used as independent style sheets, the error can be avoided by separating everything in B other than the inclusion of A into a separate style sheet B1 and changing B to contain just inclusions of B1 and A, doing the same for C, and then changing D to include A, B1, C1.

Example

XML file (collection.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="xslinclude.xsl"?>
<COLLECTION>
   <BOOK>
      <TITLE>Cosmos</TITLE>
      <AUTHOR>Carl Sagan</AUTHOR>
      <PUBLISHER>Ballantine Books</PUBLISHER>
   </BOOK>
   <BOOK>
      <TITLE>Catwings</TITLE>
      <AUTHOR>Ursula K. Le Guin</AUTHOR>
      <PUBLISHER>Scholastic</PUBLISHER>
   </BOOK>
   <BOOK>
      <TITLE>Home Town</TITLE>
      <AUTHOR>Tracy Kidder</AUTHOR>
      <PUBLISHER>Random House</PUBLISHER>
   </BOOK>
</COLLECTION>

XSLT File (xslinclude.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

<xsl:template match="/">
   <xsl:for-each select="COLLECTION/BOOK">
      <xsl:apply-templates select="TITLE"/>
      <xsl:apply-templates select="AUTHOR"/>
      <xsl:apply-templates select="PUBLISHER"/>
      <BR/>  <!-- add this -->
   </xsl:for-each>
</xsl:template>

<xsl:include href="xslincludefile.xsl" />

</xsl:stylesheet>

Included XSLT File (xslincludefile.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xsl:space="preserve">

<xsl:template match="TITLE">
   Title - <xsl:value-of select="."/><BR/>
</xsl:template>

<xsl:template match="AUTHOR">
   Author - <xsl:value-of select="."/><BR/>
</xsl:template>

<xsl:template match="PUBLISHER">
   Publisher - <xsl:value-of select="."/><BR/><!-- removed second <BR/> -->
</xsl:template>

</xsl:stylesheet>

Formatted Output

Title - Cosmos
Author - Carl Sagan
Publisher - Ballantine Books

Title - Catwings
Author - Ursula K. Le Guin
Publisher - Scholastic

Title - Home Town
Author - Tracy Kidder
Publisher - Random House

Processor Output

      Title - Cosmos<BR />
      Author - Carl Sagan<BR />
      Publisher - Ballantine Books<BR /><BR />
      Title - Catwings<BR />
      Author - Ursula K. Le Guin<BR />
...
      Publisher - Random House<BR /><BR />

See Also

xsl:import Element


xsl:key Element

The <xsl:key> element declares a named key for use with the key () function in XML Path Language (XPath) expressions for enabling easier access into complex XML documents. Keys are top-level elements, which means they cannot appear within a template.

<xsl:key
  name = Qname
  match = Pattern
  use = Expression>
</xsl:key>

Attributes

name
Identifies the key within the XSL Transformations (XSLT) document.
match
Specifies the pattern that should be matched. The Extensible Stylesheet Language (XSL) processor effectively preprocesses the source document and identifies all elements within the document that match the given pattern. Because the match is done on a node-by-node basis, it is not necessary to specify global pattern matches in the pattern string.
use
Provides the value to reference an element that satisfies the pattern specified in the match attribute. Because the context is temporarily set to that element, the value of the use attribute should be an XPath expression that identifies each particular match, such as an id or similar element.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:stylesheet
Child elements | (No child elements)

Remarks

The <xsl:key> element provides an alternative mechanism for addressing elements within an XML document. In effect, keys create a directory of specific elements from an XML source document, with the values generated from the use expressions referring to those elements. The primary difference between a key and an id is that an id must be a fixed qualified name, while a key can be created from either one or several concatenated expressions.

The <xsl:key> element is designed to be used with the XPath key() function. The key() function takes two arguments — the name of the key and its value — and then either retrieves the node or nodes associated with that key–value pair, or returns an empty node-set if no matching element is found. Unlike id elements, a key() expression may be matched by more than one node.

It is possible, of course, to create an XPath expression that retrieves the same data a key would, but when working with relatively large XML documents, a key is often faster because it essentially indexes the locations of the desired data ahead of time.

While the XSLT parser compiles the search expressions for the key element ahead of time, the current implementation does not explicitly create the index unless a key() function is encountered. This guarantees that if a transformation bypasses the key() function call then the initial time-intensive indexing is not performed. Note also that, in accordance with the Worldwide Web Consortium (W3C) specifications, parameter or variable references cannot be used as part of a <xsl:key> match, ostensibly to avoid circular references.

Example

This example defines a key named "title-search" that locates book elements that have an author attribute equal to "David Perry".

XML File (titles.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="key_sample.xsl" ?>
<titles>
   <book title="XML Today" author="David Perry"/>
   <book title="XML and Microsoft" author="David Perry"/>
   <book title="XML Productivity" author="Jim Kim"/>
</titles>

XSLT File (key_sample.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:key name="title-search" match="book" use="@author"/>

<xsl:template match="/">
   <HTML>
      <BODY>
        <xsl:for-each select="key('title-search', 'David Perry')">
         <div>
         <xsl:value-of select="@title"/>
         </div>
      </xsl:for-each>
      </BODY>
   </HTML>
</xsl:template>

</xsl:stylesheet>

Formatted Output

XML Today

XML and Microsoft

Processor Output

<HTML>
<BODY>
<div>XML Today</div>
<div>XML and Microsoft</div>
</BODY>
</HTML>

See Also

key() Function | id() Function


xsl:message Element

The <xsl:message> element sends a text message to either the message buffer or a message dialog box, depending on the environment in which the element call is made. It also raises a system-level error message that can be trapped through normal error-handling mechanisms.

<xsl:message
  terminate = "yes|no" >
</xsl:message>

Attributes

terminate
The terminate attribute indicates that the XSLT document should stop processing. The default value is "no".

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:attribute, xsl:comment, xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:processing-instruction, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | xsl:apply-templates, xsl:attribute, xsl:call-template, xsl:choose, xsl:comment, xsl:copy, xsl:copy-of, xsl:element, xsl:for-each, xsl:if, xsl:processing-instruction, xsl:text, xsl:value-of, xsl:variable, output elements

Remarks

The <xsl:message> element provides a mechanism to debug XSL Transformations (XSLT) style sheets in progress. Whenever an <xsl:message> element is encountered, if the terminate flag is set to "yes", then the XSLT processor quits, and sends a system-level error message. Expressions contained within the <xsl:message> element evaluate relative to the current context, making message a good way to watch individual elements.

If terminate is set to "no" (the default), then the Microsoft XML Parser (MSXML) 3.0 ignores the command. This is a good way to disable error handling without removing it entirely from your Extensible Stylesheet Language (XSL) style sheet, although upcoming implementations can send such messages out to a log file. (This is not currently supported.)

Example

The following sample demonstrates use of the <xsl:message> element.

The style sheet verifies that the name element within a record element has been filled in. If a name field is empty, then a message indicating that the XML is invalid is output.

In the XML file, a name is not supplied for the name element in the second record element.

XML File (records.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="message.xsl" ?>
<records>
   <record>
      <name>David Perry</name>
      <address>222 Cherry</address>
      <phone>555-797-79797</phone>
   </record>
   <record>
      <name></name>
      <address>312 Elm</address>
      <phone>555-797-79797</phone>
   </record>
</records>

XSLT File (message.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

  <xsl:template match="/">
     <xsl:apply-templates select="*"/>
     <xsl:copy-of select="."/>
  </xsl:template>

  <xsl:template match="*">
     <xsl:apply-templates select="//record"/>
  </xsl:template>

  <xsl:template match="record">
     <xsl:if test="name=''">
         <xsl:message terminate="yes">A name field is empty.
         </xsl:message>
     </xsl:if>
  </xsl:template>

</xsl:stylesheet>

Formatted Output

Internet Explorer shows the following error message:

A name field is empty.

Processor Output

<?xml version="1.0" encoding="UTF-16"?>

See Also

xsl:comment Element


xsl:namespace-alias Element

The <xsl:namespace-alias> element replaces the prefix associated with a given namespace with another prefix.

<xsl:namespace-alias
  stylesheet-prefix = Qname
  result-prefix = Qname/>

Attributes

None

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:stylesheet
Child elements | (No child elements)

Remarks

Sometimes the content that an XSL Transformations (XSLT) file generates is other XSLT. This presents a challenge with namespaces because there is no explicit way to declare two prefixes with the same namespace without the processor treating both prefixes as the same namespace and acting on them. With the namespace-alias command, you can assign an interim namespace to an alternate prefix, apply the style sheet, and then map the alternate namespace to the XSLT one.

Although XSL-to-XSL file generation is the primary use for this command, it is not the only one. You can use this technique anywhere you have colliding namespaces (for example, with the xsi: schema data type namespace). The top-level element must be <xsl:namespace-alias>.

Example

The style sheet generates a style sheet based on a couple of input parameters, and then maps the alt: prefix to the xsl: prefix.

Command Prompt Commands

This example produces XML rather than HTML. To run this example, you can use commands such as the following, or view the XML file in Internet Explorer, then right-click and select the View XSL Output utility.

cd "c:\mydir\test"
c:\bat\msxsl mymin.xml alias.xsl -o output.xsl

Processor Output (output.xsl)

The following stream is produced. Whitespace added for clarity.

<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="IERoutines.xsl" />

<xsl:template match="/">
   <div>
      <xsl:call-template name="showTable" />
   </div>
</xsl:template>

</xsl:stylesheet>

XML File (mymin.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="alias.xsl"?>
<myelem/>

XSLT File (alias.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:alt="http://www.w3.org/1999/XSL/Transform-alternate">

<xsl:namespace-alias stylesheet-prefix="alt" result-prefix="xsl"/>
<xsl:param name="browser" select="'InternetExplorer'"/>

<xsl:template match="/">
   <alt:stylesheet>
      <xsl:choose>
         <xsl:when test="$browser='InternetExplorer'">
            <alt:import href="IERoutines.xsl"/>
            <alt:template match="/">
               <div>
                  <alt:call-template name="showTable"/>
               </div>
            </alt:template>
         </xsl:when>
         <xsl:otherwise>
            <alt:import href="OtherBrowserRoutines.xsl"/>
            <alt:template match="/">
               <div>
                  <alt:call-template name="showTable"/>
               </div>
            </alt:template>
         </xsl:otherwise>
      </xsl:choose>
   </alt:stylesheet>
</xsl:template>

</xsl:stylesheet>

See Also

xsl:import Element | xsl:include Element


xsl:number Element

Inserts a formatted number into the result tree.

<xsl:number
  level = "single" | "multiple" | "any"
  count = pattern
  from = pattern
  value = number-expression
  format = { string }
  lang = { nmtoken }
  letter-value = { "alphabetic" | "traditional" }
  grouping-separator = { char }
  grouping-size = { number } />

Attributes

level
Specifies what levels of the source tree should be considered; it has the values single, multiple or any. The default is single.
count
A pattern that specifies what nodes should be counted at those levels. If the count attribute is not specified, then it defaults to the pattern that matches any node with the same node type as the current node and, if the current node has an expanded-name, with the same expanded-name as the current node.
from
A pattern that specifies where counting starts.
value
Specifies the expression to be converted to a number and output to the result tree. If no value attribute is specified, then the <xsl:number> element inserts a number based on the position of the current node in the source tree.
format
A sequence of tokens that specifies the format to be used for each number in the list. If there are no format tokens, then the default value of 1 is used which generates a sequence 1 2 … 10 11 12…. Each number after the first is separated from the preceding number by the separator token preceding the format token used to format that number. If there are no separator tokens, a period character is used ".".

Format token | Sequence generated
1 | 1 2 3 4 5 … 10 11 12 …
01 | 01 02 03 … 19 10 11 … 99 100 101…
A | A B C … Z AA AB AC…
I | i ii iii iv v vi vii viii ix x…
I | I II III IV V VI VII VIII IX X…

lang
Specifies which language's alphabet is used. If no lang value is specified, the language is determined from the system environment.
letter-value
Disambiguates between numbering sequences that use letters. One numbering sequence assigns numeric values to letters in alphabetic sequence, and the other assigns numeric values to each letter in some other manner traditional in that language. In English, these correspond to the numbering sequences specified by the format tokens "a" and "i". In some languages, the first member of each sequence is the same, and so the format token alone would be ambiguous. A value of "alphabetic" specifies the alphabetic sequence; a value of "traditional" specifies the other sequence. Default is "alphabetic."
grouping-separator
Gives the separator used as a grouping (e.g. thousands) separator in decimal numbering sequences. For example, grouping-separator="," and grouping-size="3" would produce numbers of the form 1,000,000. If only one of the grouping-separator and grouping-size attributes is specified, then it is ignored.
grouping-size
Specifies the size (normally 3) of the grouping. For example, grouping-separator="," and grouping-size="3" would produce numbers of the form 1,000,000. If only one of the grouping-separator and grouping-size attributes is specified, then it is ignored.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | (No child elements)

Remarks

The number to be inserted is specified by an expression contained in the value attribute. The expression is evaluated and the resulting object is converted to a number. The number is rounded to an integer and then converted to a string and inserted in the result tree.

The <xsl:number> element first constructs a list of positive integers using the level, count and from attributes:

  • When level="single", it goes up to the first node in the ancestor-or-self axis that matches the count pattern, and constructs a list of length one containing one plus the number of preceding siblings of that ancestor that match the count pattern. If there is no such ancestor, it constructs an empty list. If the from attribute is specified, then the only ancestors that are searched are those that are descendants of the nearest ancestor that matches the from pattern. Preceding-siblings has the same meaning here as with the preceding-sibling axis.
  • When level="multiple", it constructs a list of all ancestors of the current node in document order followed by the element itself; it then selects from the list those nodes that match the count pattern; it then maps each node in the list to one plus the number of preceding siblings of that node that match the count pattern. If the from attribute is specified, then the only ancestors that are searched are those that are descendants of the nearest ancestor that matches the from pattern. Preceding siblings has the same meaning here as with the preceding-sibling axis.
  • When level="any", it constructs a list of length one containing the number of nodes that match the count pattern and belong to the set containing the current node and all nodes at any level of the document that are before the current node in document order, excluding any namespace and attribute nodes (in other words the union of the members of the preceding and ancestor-or-self axes). If the from attribute is specified, then only nodes after the first node before the current node that match the from pattern are considered.

The following languages/numbering schemes are supported. "Format Token" corresponds to the format attribute, "Language" corresponds to the "lang" attribute, and "Letter-Value" corresponds to the letter-value attribute.

Description | Format Token | Language | Letter-Value
Western | 0x0031 (1) | n/a | n/a
Upper-case letter | 0x0041 (A) | n/a | n/a
Lower-case letter | 0x0061 (a) | n/a | n/a
Upper-case Roman | 0x0049 (I) | n/a | n/a
Lower-case Roman | 0x0069 (i) | n/a | n/a
Upper-case Russian (Cyrillic) | 0x0410 | n/a | n/a
Lower-case Russian (Cyrillic) | 0x0430 | n/a | n/a
Hebrew Alphabetic | 0x05d0 | n/a | Alphabetic
Hebrew Traditional | 0x05d0 | n/a | Traditional
Arabic | 0x0623 | n/a | n/a
Hindi Consonants | 0x0905 | n/a | n/a
Hindi Vowels | 0x0915 | n/a | n/a
Hindi Numbers | 0x0967 | n/a | n/a
Thai Letters | 0x0e01 | n/a | n/a
Thai Numbers | 0x0e51 | n/a | n/a
Japanese Aiueo (double-byte) | 0x30a2 | n/a | n/a
Japanese Iroha (double-byte) | 0x30a4 | n/a | n/a
Korean Chosung | 0x3131 | n/a | n/a
Taiwanese Decimal | 0x4e01 | "zh-tw" | n/a
Korean Decimal | 0x4e01 | "ko" | n/a
Asian Decimal | 0x4e01 | any other lang | n/a
Asian Kanji | 0x58f1 | n/a | n/a
Traditional Taiwanese | 0x58f9 | "zh-tw" | n/a
Traditional Chinese | 0x58f9 | any other lang | n/a
Chinese "Zodiac" 12 | 0x5b50 | n/a | n/a
Chinese "Zodiac" 10 | 0x7532 | n/a | n/a
Chinese "Zodiac" 60 | 0x7532, 0x5b50 | n/a | n/a
Korean Ganada | 0xac00 | n/a | n/a
Korean Decimal | 0xc77c | n/a | n/a
Korean 99 | 0xd558 | n/a | n/a
Western (double-byte) | 0xff11 | n/a | n/a
Japanese Aiueo (single-byte) | 0xff71 | n/a | n/a
Japanese Iroha (single-byte) | 0xff72 | n/a | n/a

If the format token alone is enough to disambiguate a particular numbering scheme, there is no need to specify the language or letter-value.

Here are some examples of conversion specifications.

format="&#x30A2;" specifies Katakana numbering.

format="&#x30A4;" specifies Katakana numbering in the "iroha" order.

format="&#x0E51;" specifies numbering with Thai digits.

format="&#x05D0;" letter-value="traditional" specifies "traditional" Hebrew numbering.

format="&#x10D0;" letter-value="traditional" specifies Georgian numbering.

format="&#x03B1;" letter-value="traditional" specifies "classical" Greek numbering.

format="&#x0430;" letter-value="traditional" specifies Old Slavic numbering.

Example

This example demonstrates the use of the <xsl:number> element by numbering items in a sorted list with Western and then lower-case Roman numbering.

XML File (items.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="numelem.xsl" ?>
<items>
   <item>Car</item>
   <item>Pen</item>
   <item>LP Record</item>
   <item>Wisdom</item>
   <item>Cell phone</item>
   <item>Film projector</item>
   <item>Hole</item>
   <item>Canopy</item>
   <item>Widget</item>
   <item>Concept</item>
   <item>Null character</item>
</items>

XSLT File (numelem.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:template match="items">
   <xsl:for-each select="item">
      <xsl:sort select="."/>
      <xsl:number value="position()" format="1. "/>
      <xsl:value-of select="."/>,
      <xsl:number value="position()" format="&#x0069;) "/>
      <xsl:value-of select="."/>
      <br/>
   </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Formatted Output

1. Canopy, i) Canopy
2. Car, ii) Car
3. Cell phone, iii) Cell phone
4. Concept, iv) Concept
5. Film projector, v) Film projector
6. Hole, vi) Hole
7. LP Record, vii) LP Record
8. Null character, viii) Null character
9. Pen, ix) Pen
10. Widget, x) Widget
11. Wisdom, xi) Wisdom

Processor Output

<?xml version="1.0" encoding="UTF-16"?>1. Canopy,
      i) Canopy<br />2. Car,
      ii) Car<br />3. Cell phone,
...
      xi) Wisdom<br />

See Also

Inserting Automatic Numbering Using XSLT


xsl:otherwise Element

Provides multiple conditional testing in conjunction with the <xsl:choose> and <xsl:when> elements.

<xsl:otherwise>
</xsl:otherwise>

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:choose
Child elements | xsl:apply-templates, xsl:attribute, xsl:call-template, xsl:choose, xsl:comment, xsl:copy, xsl:copy-of, xsl:element, xsl:for-each, xsl:if, xsl:processing-instruction, xsl:text, xsl:value-of, xsl:variable, output elements

Remarks

Provides a default condition for <xsl:choose>. Other alternatives are indicated by <xsl:when> elements.

For simple conditional testing, use the <xsl:if> element.

Example

See the example for xsl:choose.

See Also

Defining Conditional Templates Using <xsl:if> and <xsl:choose> | xsl:when


xsl:output Element

Specifies options for use in serializing the result tree.

<xsl:output
  method = "xml" | "html" | "text"
  version = nmtoken
  encoding = string
  omit-xml-declaration = "yes" | "no"
  standalone = "yes" | "no"
  doctype-public = string
  doctype-system = string
  cdata-section-elements = qnames
  indent = "yes" | "no"
  media-type = string
  />

Attributes

method
Identifies the overall method used for outputting the result tree. If there is no prefix, it identifies a method specified in this document that must be one of "xml", "html", or "text". If there is a prefix, it is expanded and identifies the output method.

The default for the method attribute is chosen as follows. If any of the following conditions are true, the default output method is "html":

  • The root node of the result tree has an element child.
  • The expanded-name of the first element child of the root node (that is, the document element) of the result tree has local part "html" (in any combination of uppercase and lowercase) and a null namespace URI.
  • Any text nodes preceding the first element child of the root node of the result tree contain only white space characters.

Otherwise, the default output method is "xml". The default output method should be used if there are no <xsl:output> elements or if none of the <xsl:output> elements specifies a value for the method attribute.

version
Specifies version "1.0" in relation to the "xml" output method; this appears in the output XML declaration as <?xml version="1.0"?>.
encoding
Specifies the preferred character encoding that the parser should use to encode sequences of characters as sequences of bytes. The value of the attribute is treated case-insensitively; it must contain only printable ASCII characters and be a registered character set, or begin with x-.
omit-xml-declaration
Specifies whether the XSLT processor should output an XML declaration; the value must be yes or no.
standalone
Specifies whether the XSLT processor should output a standalone document declaration; the value must be yes or no.
doctype-public
Specifies the public identifier to be used in the DTD.
doctype-system
Specifies the system identifier to be used in the DTD.
cdata-section-elements
Specifies a list of the names of elements whose text node children should be output using CDATA sections.
indent
Specifies additional white space to add when outputting the result tree; the value must be yes or no.
media-type
Specifies the media type (MIME content type) of the data that results from outputting the result tree.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:stylesheet, xsl:transform
Child elements | (No child elements)

Remarks

A style sheet may contain multiple <xsl:output> elements and may include style sheets that also contain <xsl:output> elements. All the <xsl:output> elements occurring in a style sheet are merged into a single effective <xsl:output> element. It is an error if there is more than one such value for an attribute. The values of attributes are defaulted after the <xsl:output> elements have been merged; different output methods may have different default values for an attribute.

Example 1

This is a simple Hello World demonstration.

XML File (hello.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="hello.xsl"?>
<messages>
   <message>Hello World!</message>
</messages>

XSLT File (hello.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template match="//message">
   <html>
      <head>
         <title>Message</title>
      </head>
      <body>
         <p><xsl:value-of select="."/></p>
      </body>
   </html>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Hello World!

Processor Output

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-16">
<title>Message</title>
</head>
<body>
<p>Hello World!</p>
</body>
</html>

Example 2

This example outputs the result tree as HTML.

XML File (booksshort.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="outputelem.xsl"?>
<catalog>
    <book id="bk101">
        <author>Gambardella, Matthew</author>
        <title>XML Developer's Guide</title>
        <genre>Computer</genre>
        <price>44.95</price>
        <publish_date>2000-10-01</publish_date>
        <description>An in-depth look at creating applications with
 XML.</description>
    </book>
    <book id="bk102">
        <author>Ralls, Kim</author>
        <title>Midnight Rain</title>
        <genre>Fantasy</genre>
        <price>5.95</price>
        <publish_date>2000-12-16</publish_date>
        <description>A former architect battles corporate zombies,
 an evil sorceress, and her own childhood to become queen of the
 world.</description>
    </book>
    <book id="bk103">
        <author>Corets, Eva</author>
        <title>Maeve Ascendant</title>
        <genre>Fantasy</genre>
        <price>5.95</price>
        <publish_date>2000-11-17</publish_date>
        <description>After the collapse of a nanotechnology society
 in England, the young survivors lay the foundation for a new
society.</description>
    </book>
</catalog>

XSLT File (outputelem.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="html" version="4.0"/>

<xsl:template match="/">
  <html>
    <xsl:apply-templates/>
  </html>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Gambardella, MatthewXML Developer's GuideComputer44.952000-10-01An in-depth
look at creating applications with XML.Ralls, KimMidnight RainFantasy5.952000-12-16A
former architect battles corporate zombies, an evil sorceress, and her own childhood to
become queen of the world.Corets, EvaMaeve AscendantFantasy5.952000-11-17After
the collapse of a nanotechnology society in England, the young survivors lay the
foundation for a new society.

Processor Output

<html>Gambardella, MatthewXML Developer's GuideComputer44.952000-10-01
An in-depth look at creating applications with XML.Ralls, KimMidnight
RainFantasy5.952000-12-16A former architect battles corporate zombies,
 an evil sorceress, and her own childhood to become queen of the
 world.Corets, EvaMaeve AscendantFantasy5.952000-11-17After the collapse
of a nanotechnology society in England, the young survivors lay the
foundation for a new society.</html>


xsl:param Element

Declares a named parameter for use within an xsl:stylesheet or xsl:template. Allows specification of a default value.

<xsl:param
  name = Qname
  select = expression>
</xsl:param>

Attributes

name
Required. Specifies the name of the parameter.
select
The value of the attribute is an expression, and the value of the variable is the object that results from evaluating the expression. When this attribute is specified, the content of <xsl:param> must be empty.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:stylesheet, xsl:template, xsl:transform
Child elements | xsl:apply-templates, xsl:attribute, xsl:call-template, xsl:choose, xsl:comment, xsl:copy, xsl:copy-of, xsl:element, xsl:for-each, xsl:if, xsl:processing-instruction, xsl:text, xsl:value-of, xsl:variable, output elements

Remarks

The value specified on the <xsl:param> element is a default value for binding. When the template or style sheet containing <xsl:param> is invoked, parameters are passed that are used in place of the default values.

The <xsl:param> element must be declared as a direct child of an <xsl:template> element. If not declared as a direct child, the value of the <xsl:param> element will not be accessible and an error will occur. For example:

<xsl:template name="getcount">
   <xsl:element name="strong">
      <xsl:param name="counted">
         <xsl:value-of select="count(//book)"/>
      </xsl:param>
      Total Book Count: <xsl:value-of select="$counted"/>
   </xsl:element>
</xsl:template>

In the previous example, the only direct child of the <xsl:template> element is the strong element. As such, the value of the <xsl:param> element can not be correctly evaluated by the parser and results in the following error:

Keyword xsl:param may not be used here.

The correct way to place this element so that it can be evaluated within the context of the <xsl:template> element would be:

<xsl:template name="getcount">
   <xsl:param name="counted">
      <xsl:value-of select="count(//book)"/>
   </xsl:param>
   <xsl:element name="strong">
      Total Book Count: <xsl:value-of select="$counted"/>
   </xsl:element>

The value of the parameter can be an object of any type that can be returned by an expression. The <xsl:param> element can specify the value of the variable in three alternative ways:

  • If the element has a select attribute, the value of the attribute must be an expression and the value of the parameter is the object that results from evaluating the expression. In this case, the content of the element must be empty.
  • If the element does not have a select attribute and has non-empty content such as one or more child nodes, the content specifies the value. The content is a template that is instantiated to give the value of the parameter. The value is a result-tree fragment equivalent to a node-set containing just a single root node having as children the sequence of nodes produced by instantiating the template. The base URI of the nodes in the result-tree fragment is the base URI of the element.

    An error occurs if a member of the sequence of nodes created by instantiating the template is an attribute node or a namespace node, because a root node cannot have an attribute node or a namespace node as a child.

  • If the content is empty and does not have a select attribute, the value of the parameter is an empty string. Thus
    <xsl:param name="x"/>

    is equivalent to

    <xsl:param name="x" select="''"/>
    Note When a parameter is used to select nodes by position, be careful not to do the following:
    <xsl:param name="n">2</xsl:param>
...
<xsl:value-of select="item[$n]"/>

    This will output the value of the first item element, because the variable "n" will be bound to a result-tree fragment, not a number. Instead, do either

    <xsl:param name="n" select="2"/>
...
<xsl:value-of select="item[$n]"/>

    or

    <xsl:param name="n">2</xsl:param>
...
<xsl:value-of select="item[number($n)]"/>
    Note The following is a convenient way to specify the empty node-set as the default value of a parameter.
    <xsl:param name="x" select="/.."/>

Example

This example defines a named template for a "numbered-block" with an argument to control the format of the number.

XML File (catmat.xml)

None; the XSLT file calls itself. View the XSLT file in Internet Explorer.

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="paramelem.xsl"?>
<lists>
   <ol>
      <li>the</li>
      <li>cat</li>
      <ol>
         <li>sat</li>
         <li>on</li>
         <li>the</li>
      </ol>
      <li>mat</li>
   </ol>
</lists>

XSLT File (paramelem.xsl)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="paramelem.xsl"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl:template match="ol/li">
   <br/>
   <xsl:call-template name="numbered-block"/>
</xsl:template>

<xsl:template match="ol//ol/li">
   <br/>&#xA0;&#xA0;&#xA0;
   <xsl:call-template name="numbered-block">
      <xsl:with-param name="format">a. </xsl:with-param>
   </xsl:call-template>
</xsl:template>

<xsl:template name="numbered-block">
   <xsl:param name="format">1. </xsl:param>
   <fo:block>
      <xsl:number format="{$format}"/>
      <xsl:apply-templates/>
   </fo:block>
</xsl:template>

</xsl:stylesheet>

Formatted Output

1. the
2. cat
a. sat
b. on
c. the
3. mat

Processor Output

White space added for clarity.

<?xml version="1.0" encoding="UTF-16"?>
<br xmlns:fo="http://www.w3.org/1999/XSL/Format" />
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format">1. the</fo:block>
<br xmlns:fo="http://www.w3.org/1999/XSL/Format" />
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format">2. cat</fo:block>
<br xmlns:fo="http://www.w3.org/1999/XSL/Format" />

<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format">a. sat</fo:block>
<br xmlns:fo="http://www.w3.org/1999/XSL/Format" />

<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format">b. on</fo:block>
<br xmlns:fo="http://www.w3.org/1999/XSL/Format" />

<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format">c. the</fo:block>
<br xmlns:fo="http://www.w3.org/1999/XSL/Format" />
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format">3. mat</fo:block>

See Also

xsl:with-param Element | xsl:variable Element | xsl:call-template Element


xsl:preserve-space Element

Preserves white space in a document.

<xsl:preserve-space
  elements = tokens />

Attributes

elements
Required. White space-separated list of name tests.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:stylesheet, xsl:transform
Child elements | (No child elements)

Remarks

<xsl:preserve-space> is a white space-preserving element and has an elements attribute whose value is a white space-separated list of name tests. Initially, the set of white space-preserving element names contains all element names. If an element name matches a name test in an <xsl:strip-space> element, then it is removed from the set of white space-preserving element names. If an element name matches a name test in an <xsl:preserve-space> element, then it is added to the set of white space-preserving element names. An element matches a name test if and only if the name test would be true for the element as an XML Path Language (XPath) node test. The applicable match for a particular element name is determined as follows.

  • First, any match with lower import precedence than another match is ignored.
  • Next, any match with a name test that has a lower default priority than the default priority of the name test of another match is ignored.
  • It is an error if this leaves more than one match.

Example

See Preserving or Stripping White Space.

See Also

xsl:strip-space Element | Controlling White Space with XSLT


xsl:processing-instruction Element

Generates a processing instruction in the output.

<xsl:processing-instruction
  name = "pi-name">
</xsl: processing-instruction>

Attributes

name
Required. Name of the processing instruction.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:attribute, xsl:comment, xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:processing-instruction, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | xsl:apply-imports, xsl:apply-templates, xsl:call-template, xsl:choose, xsl:copy, xsl:copy-of, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:number, xsl:text, xsl:value-of, xsl:variable, output elements

Remarks

The <xsl:processing-instruction> element generates a processing instruction in the output. The name is indicated by the name attribute. The content of the element provides the rest of the processing instruction.

The XML declaration is not a processing instruction, and should be generated by setting attributes on xsl:output.

Example

This example shows a template that generates the XML declaration and a style sheet processing instruction in the output.

XML File (customers.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="pi.xsl" ?>
<customers>
<customer>
   <name>John Smith</name>
   <address>123 Elm St.</address>
   <phone>(123) 456-7890</phone>
</customer>
<customer>
   <name>Mary Jones</name>
   <address>456 Oak Ave.</address>
   <phone>(156) 789-0123</phone>
</customer>
</customers>

XSLT File (pi.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:output method='xml' version='1.0'/>
<xsl:template match="/">
  <xsl:processing-instruction name="xml-stylesheet">
  <xsl:text>type="text/xsl" href="style.xsl"</xsl:text>
  </xsl:processing-instruction>
  <xsl:apply-templates />
</xsl:template>

</xsl:stylesheet>

See Also

Generating Comments, Processing Instructions, and Elements


msxsl:script Element

Appears at the top level of the style sheet and contains script blocks that define global variables and functions for script extensions.

<msxsl:script
  language = "language-name"
  implements-prefix = "prefix of user's namespace">
</msxsl:script>

Attributes

language
Active Scripting language used for the functions defined within this element. If left unspecified, Microsoft® JScript® (compatible with ECMA 262 language specification) is used. This attribute accepts the same values as the language attribute on the HTML <SCRIPT> element.
implements-prefix
Required. Declares a namespace and associates it with the script block. The value of this attribute is the prefix that represents the namespace.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:stylesheet, xsl:transform
Child elements | (No child elements)

Remarks

The msxsl:script element belongs to the namespace urn:schemas-microsoft-com:xslt. You can declare variables and define functions within this element. This element can appear within the <xsl:stylesheet> element. A script block thus nested is treated as a global script block.

You can also instantiate COM objects in the <msxsl:script> element. However, a user's security settings may prevent your script from instantiating a client-side object.

For high performance, eliminate script blocks from XSLT files, because they require loading the script engine multiple times. Instead, create a COM object that is equivalent to the script, producing a DLL. Then use addObject and pass the DLL.

Example

This example defines a script block with a namepace prefix of "user" that contains a function called "xml" that takes a node-list as an argument. Later, this function, xml(nodelist) in the user namespace, is called from the select attribute of <xsl:value-of>.

XML File (customers.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="script.xsl" ?>
<customers>
   <customer>
      <name>John Smith</name>
      <address>123 Elm St.</address>
      <phone>(123) 456-7890</phone>
   </customer>
   <customer>
      <name>Mary Jones</name>
      <address>456 Oak Ave.</address>
      <phone>(156) 789-0123</phone>
   </customer>
</customers>

XSLT File (script.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
      xmlns:user="http://mycompany.com/mynamespace">

<msxsl:script language="JScript" implements-prefix="user">
   function xml(nodelist) {
      return nodelist.nextNode().xml;
   }
</msxsl:script>

<xsl:template match="/">
   <xsl:value-of select="user:xml(.)"/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="script.xsl" ?> <customers> <customer> <name>John Smith</name> <address>123 Elm St.</address> <phone>(123) 456-7890</phone> </customer> <customer> <name>Mary Jones</name> <address>456 Oak Ave.</address> <phone>(156) 789-0123</phone> </customer> </customers>

Processor Output

The script moves through all the nodes of the input file, producing the following output stream.

<?xml version="1.0" encoding="UTF-16"?>&lt;?xml version="1.0"?&gt;
&lt;?xml-stylesheet type="text/xsl" href="script.xsl" ?&gt;
&lt;customers&gt;
 &lt;customer&gt;
  &lt;name&gt;John Smith&lt;/name&gt;
  &lt;address&gt;123 Elm St.&lt;/address&gt;
  &lt;phone&gt;(123) 456-7890&lt;/phone&gt;
 &lt;/customer&gt;
 &lt;customer&gt;
  &lt;name&gt;Mary Jones&lt;/name&gt;
  &lt;address&gt;456 Oak Ave.&lt;/address&gt;
  &lt;phone&gt;(156) 789-0123&lt;/phone&gt;
 &lt;/customer&gt;
&lt;/customers&gt;

See Also

xsl:value-of Element


xsl:sort Element

Specifies sort criteria for node lists selected by xsl:for-each or xsl:apply-templates.

<xsl:sort
  select = string-expression
  data-type = { "text" | "number" | Qname }
  order = { "ascending" | "descending" }
  lang = { nmtoken }
  case-order = { "upper-first" | "lower-first" }
  />

Attributes

select
Specifies a sort key for the node. An expression that is evaluated with the specified node as the current node and with the complete list of nodes being processed in unsorted order as the current node-list. The resulting object is converted to a string that is used as the sort key for that node. The default value of the select attribute is ".". This causes the string-value of the current node to be used as the sort key.
data-type
Specifies the data type of the strings. The following values are allowed.

"text" | Specifies that the sort keys should be sorted alphabetically.
Number | Specifies that the sort keys should be converted to numbers and then sorted according to the numeric value. The sort key is converted to a number.
Qname | Expanded into a dt-expanded-name. The expanded-name identifies the data type.

If no data type is specified, the type of the expression will be used as the default.

order
Specifies whether the strings will be sorted in ascending or descending order. The default is ascending.
case-order
Specifies whether the strings will be sorted with lower-case or uppercase characters specified first. The default is upper-first.
lang
Specifies which language's alphabet is used to determine sort order. If no lang value is specified, the language is determined from the system environment.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:apply-templates, xsl:for-each
Child elements | (No child elements)

Remarks

This sorting algorithm ignores dashes when sorting. This is the "word-sort" method, intended to sort words like "co-op" next to "coop".

For example, the following sort order is produced:

30a-allow

30-allow

Thus the sort treats the items as though they were:

30aallow

30allow

Example

See the example in Sorting XML Using <xsl:sort>.

See Also

Sorting XML Using <xsl:sort>


xsl:strip-space Element

Strips white space in a document.

<xsl:strip-space
  elements = tokens />

Attributes

elements
Required. White space-separated list of name tests.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:stylesheet, xsl:transform
Child elements | (No child elements)

Remarks

<xsl:strip-space> is a white space-preserving element and has an elements attribute whose value is a white space-separated list of name tests. Initially, the set of white space-preserving element names contains all element names. If an element name matches a name test in an <xsl:strip-space> element, then it is removed from the set of white space-preserving element names. If an element name matches a name test in an <xsl:preserve-space> element, then it is added to the set of white space-preserving element names. An element matches a name test if and only if the name test would be true for the element as an XML Path Language (XPath) node test. The applicable match for a particular element name is determined as follows:

  • First, any match with lower import precedence than another match is ignored.
  • Next, any match with a name test that has a lower default priority than the default priority of the name test of another match is ignored.
  • It is an error if this leaves more than one match.

Example

The command prompt approach demonstrates the .preserveWhiteSpace = true property on the DOM. The results are different depending on the value of this property. When run in Internet Explorer (by the MIME viewer), the property is set to false, which can't be changed. Internet Explorer doesn't preserve white space, so fewer text nodes are reported.

XML File (cat.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="stripspc.xsl"?>
<catalog>
   <book id="bk104">
      <author>Corets, Eva</author>
      <title>Oberon's Legacy</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2001-03-10</publish_date>
      <description>In post-apocalypse England, the mysterious agent known
only as Oberon helps to create a new life for the inhabitants of London.
Sequel to Maeve Ascendant.</description>
   </book>
   <book id="bk112">
      <author>Galos, Mike</author>
      <title>Visual Studio 7: A Comprehensive Guide</title>
      <genre>Computer</genre>
      <price>49.95</price>
      <publish_date>2001-04-16</publish_date>
      <description>Microsoft Visual Studio 7 is explored in depth, looking
at how Visual Basic, Visual C++, C#, and ASP+ are integrated into a
comprehensive development environment.</description>
   </book>
</catalog>

XSLT File (stripspc.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:strip-space elements="book"/>

<xsl:template match="/">
   <html>
      <body>
         <xsl:value-of select="count(//text())"/> nodes of type text were found.
      </body>
   </html>
</xsl:template>

</xsl:stylesheet>

Formatted Output

The following output is shown when you view the XML file in Internet Explorer:

12 nodes of type text were found.

The following output is shown when you run the transformation at the command
prompt and view output.html in Internet Explorer.

15 nodes of type text were found.

Example command prompt commands are shown here:

cd "c:\mydir\test"
c:\bat\msxsl cat.xml stripspc.xsl -o output.html

Processor Output

<html>
<body>12 nodes of type text were found.
      </body>
</html>

See Also

xsl:preserve-space Element | Controlling White Space with XSLT


xsl:stylesheet Element

The document element of a style sheet, containing all other style sheet elements. This element is a synonym for the <xsl:transform> element.

<xsl:stylesheet
  id = "id"
  extension-element-prefixes = "prefixes"
  exclude-result-prefixes = "prefixes"
  version = "number">
</xsl:stylesheet>

Attributes

version
Required. Indicates the version of XSL Transformations (XSLT) the style sheet requires. Value should be set to 1.0 for this version of XSLT.
id
Specifies a unique identifier to facilitate embedding style sheets.
extension-element-prefixes
Designates a namespace as an extension namespace. The value is a white-space separated list of namespace prefixes. The namespace bound to each of the prefixes is designated as an extension namespace. The default namespace (as declared by xmlns) may be designated as an extension namespace by including #default in the list of namespace prefixes. The designation of a namespace as an extension namespace is effective within the subtree of the style sheet rooted at the element bearing the extension-element-prefixes; a subtree rooted at an xsl:stylesheet element does not include any style sheets imported or included by children of that <xsl:stylesheet> element.
exclude-result-prefixes
Designates a namespace Uniform Resource Identifier (URI) as an excluded namespace. The value is a white-space separated list of namespace prefixes. The namespace bound to each of the prefixes is designated as an excluded namespace. The default namespace (as declared by xmlns) may be designated as an excluded namespace by including #default in the list of namespace prefixes. The designation of a namespace as an excluded namespace is effective within the subtree of the style sheet rooted at the element bearing the exclude-result-prefixes; a subtree rooted at an xsl:stylesheet element does not include any style sheets imported or included by children of that <xsl:stylesheet> element.

Element Information

Number of occurrences | One
Parent elements | (No parent elements)
Child elements | xsl:attribute-set, xsl:import, xsl:include, xsl:output, xsl:param, xsl:template, xsl:variable, msxsl:script

Remarks

A style sheet contains the <xsl:stylesheet> element. This element can have a set of <xsl:template> elements representing different output templates. Processing begins by processing the root template, indicated by the pattern "/".

The following example shows a stylesheet element with several common namespaces.

<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
      xmlns:fo="http://www.w3.org/1999/XSL/Format">

Example

This example shows a complete XSLT style sheet that contains a set of templates. The root template (match="/") defines the structure of the overall output document, and the other templates define the structure of the name, address, and phone elements. This HTML output file was produced by using msxml.exe at the command prompt.

XML File (customers.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="customers.xsl"?>
<customers>
   <customer>
      <name>John Smith</name>
      <address>123 Elm St.</address>
      <phone>(123) 456-7890</phone>
   </customer>
   <customer>
      <name>Mary Jones</name>
      <address>456 Oak Ave.</address>
      <phone>(156) 789-0123</phone>
   </customer>
</customers>

XSLT File (customers.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <HTML>
    <BODY>
      <TABLE>
        <xsl:for-each select="customers/customer">
          <TR>
            <xsl:apply-templates select="name" />
            <xsl:apply-templates select="address" />
            <xsl:apply-templates select="phone" />
          </TR>
        </xsl:for-each>
      </TABLE>
    </BODY>
  </HTML>
</xsl:template>

<xsl:template match="name">
  <TD STYLE="font-size:14pt font-family:serif">
    <xsl:apply-templates />
  </TD>
</xsl:template>

<xsl:template match="address">
  <TD> <xsl:apply-templates /> </TD>
</xsl:template>

<xsl:template match="phone">
  <TD> <xsl:apply-templates /> </TD>
</xsl:template>

<xsl:template match="text()">
  <xsl:value-of select='.'/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

<HTML>
<BODY>
<TABLE>
<TR>
<TD STYLE="font-size:14pt font-family:serif">John Smith</TD>
<TD>123 Elm St.</TD>
<TD>(123) 456-7890</TD>
</TR>
<TR>
<TD STYLE="font-size:14pt font-family:serif">Mary Jones</TD>
<TD>456 Oak Ave.</TD>
<TD>(156) 789-0123</TD>
</TR>
</TABLE>
</BODY>
</HTML>

See Also

xsl:transform Element

Working with Namespaces and Prefix Aliases


xsl:template Element

Defines a reuseable template for generating the desired output for nodes of a particular type and context.

<xsl:template
  name= Qname
  match = pattern
  priority = "number"
  mode = Qname
</xsl:template>

Attributes

name
The value of the name attribute is a Qname that is expanded. If it has a prefix, the prefix is expanded into a Uniform Resource Identifier (URI) reference using the namespace declarations in effect on the attribute in which the name occurs. The expanded-name, consisting of the local part of the name and the possibly null URI reference is used as the name of the template. The default namespace is not used for unprefixed names. If an <xsl:template> element has a name attribute, it may, but need not, also have a match attribute.
match
A pattern that identifies the source node or nodes to which the rule applies. The match attribute is required unless the <xsl:template> element has a name attribute. The content of the <xsl:template> element is the template that is instantiated when the template rule is applied.
priority
All matching template rules that have lower priority than the matching template rule or rules with the highest priority are eliminated from consideration. The value of this must be a real number from 0–9, positive or negative, matching the production number with an optional leading minus sign (-). The default priority is computed as follows:
  • If the pattern contains multiple alternatives separated by |, it is treated equivalently to a set of template rules, one for each alternative.
  • If the pattern has the form of a Qname preceded by a child or attribute axis specifier or has the form processing-instruction literal preceded by a child or attribute axis specifier, the priority is 0.
  • If the pattern is a name preceded by a child or attribute axis specifier, the priority is -0.25.
  • Otherwise, if the pattern consists of just a node test preceded by a child or attribute axis specifier, the priority is -0.5.
  • Otherwise, the priority is 0.5.

Thus the most common kind of pattern (a pattern that tests for a node with a particular type and a particular expanded-name) has priority 0. The next less specific kind of pattern (a pattern that tests for a node with a particular type and an expanded-name with a particular namespace URI) has priority -0.25. Patterns less specific than this (patterns that just test for nodes with particular types) have priority -0.5. Patterns more specific than the most common kind of pattern have priority 0.5.

mode
The mode attribute allows an element to be processed multiple times, each time producing a different result. If <xsl:template> does not have a match attribute, it must not have a mode attribute. If an <xsl:apply-templates> element has a mode attribute, it applies only to those template rules from <xsl:template> elements that have a mode attribute with the same value; if an <xsl:apply-templates> element does not have a mode attribute, it applies only to those template rules from <xsl:template> elements that do not have a mode attribute.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:stylesheet, xsl:transform
Child elements | xsl:apply-imports , xsl:apply-templates, xsl:attribute, xsl:call-template, xsl:choose, xsl:comment, xsl:copy, xsl:copy-of, xsl:element, xsl:fallback , xsl:for-each, xsl:if, xsl:message, xsl:number, xsl:param, xsl:processing-instruction, xsl:text, xsl:value-of, xsl:variable, output elements

Remarks

Note that the template need not generate a complete XML document (even the root template, unless using transformNodeToObject), but only a fragment of XML. It is possible to include unenclosed text or multiple document elements defined by the template. This facilitates the generation of raw text and XML fragments that can be further processed by an application (for example, HTML fragments inserted into an HTML page).

The value of the name attribute is a Qname that is expanded. If it has a prefix, it is expanded into a URI reference using the namespace declarations in effect on the attribute in which the name occurs. The expanded-name consisting of the local part of the name and the possibly null URI reference is used as the name of the template. The default namespace is not used for unprefixed names.

If an <xsl:template> element has a name attribute, it may, but need not, also have a match attribute. An <xsl:call-template> element invokes a template by name; it has a required name attribute that identifies the template to be invoked. Unlike <xsl:apply-templates>, <xsl:call-template> does not change the current node or the current node list.

An error occurs if a style sheet contains more than one template with the same name.

Example

This template rule has a pattern that identifies elements of type "stock" and produces an output <DIV> element with the attribute STYLE="font-weight:bold":

XML File (portfolio.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="templ.xsl"?>
<portfolio xmlns:dt="urn:schemas-microsoft-com:datatypes" xml:space="preserve">
  <stock exchange="nyse">
    <name>zacx corp</name>
    <symbol>ZCXM</symbol>
    <price dt:dt="number">28.875</price>
  </stock>
  <stock exchange="nasdaq">
    <name>zaffymat inc</name>
    <symbol>ZFFX</symbol>
    <price dt:dt="number">92.250</price>
  </stock>
  <stock exchange="nasdaq">
    <name>zysmergy inc</name>
    <symbol>ZYSZ</symbol>
    <price dt:dt="number">20.313</price>
  </stock>
</portfolio>

XSLT File (templ.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="stock">
   <DIV STYLE="font-weight:bold">
      Symbol: <xsl:value-of select="symbol" />,
      Price: <xsl:value-of select="price" />
   </DIV>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Symbol: ZCXM, Price: 28.875

Symbol: ZFFX, Price: 92.250

Symbol: ZYSZ, Price: 20.313

See Also

transformNodeToObject Method


xsl:text Element

Generates text in the output.

<xsl:text
  disable-output-escaping = "yes" | "no">
</xsl:text>

Attributes

disable-output-escaping
Default is "no". If the value is "yes", a text node generated by instantiating the <xsl:text> element will be output without any escaping. For example, the following generates the single character "<".
<xsl:text disable-output-escaping="yes">&lt;</xsl:text>
Note disable-output-escaping="yes" can be used to generate non-well-formed documents, and thus should be used with caution, since non-well-formed output may generate errors in certain circumstances. For example, transformNodeToObject to an XML document requires that the result be well-formed and thus may not complete if disable-output-escaping has affected the well-formedness of the document. Consider disable-output-escaping="yes" an advanced feature to be used only when the potential dangers are understood.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:attribute, xsl:comment, xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:otherwise, xsl:message, xsl:param, xsl:processing-instruction, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | (No child elements)

Remarks

A text node is created for each <xsl:text> element appearing in a template. White space is stripped, and adjacent text nodes are automatically merged.

See Also

xsl:comment Element


xsl:transform Element

The document element of a style sheet containing <xsl:template> and <msxsl:script> elements. Synonym for xsl:stylesheet.

<xsl:transform
  id = id
  extension-element-prefixes = tokens
  exclude-result-prefixes = tokens
  version = number>
  <!-- Content: (xsl:import*, top-level-elements) -->
</xsl:transform>

Attributes

version
Required. Indicates the version of XSL Transformations (XSLT) the style sheet requires. Value should be set to 1.0 for this version of XSLT.
id
Specifies a unique identifier to facilitate embedding style sheets.
extension-element-prefixes
Designates a namespace as an extension namespace. The value is a white space-separated list of namespace prefixes. The namespace bound to each of the prefixes is designated as an extension namespace. The default namespace (as declared by xmlns) may be designated as an extension namespace by including #default in the list of namespace prefixes. The designation of a namespace as an extension namespace is effective within the subtree of the style sheet rooted at the element bearing the extension-element-prefixes; a subtree rooted at an xsl:stylesheet element does not include any style sheets imported or included by children of that <xsl:stylesheet> element.
exclude-result-prefixes
Designates a namespace URI as an excluded namespace. The value is a white-space separated list of namespace prefixes. The namespace bound to each of the prefixes is designated as an excluded namespace. The default namespace (as declared by xmlns) may be designated as an excluded namespace by including #default in the list of namespace prefixes. The designation of a namespace as an excluded namespace is effective within the subtree of the style sheet rooted at the element bearing the exclude-result-prefixes; a subtree rooted at an xsl:stylesheet element does not include any style sheets imported or included by children of that <xsl:stylesheet> element.

Element Information

Number of occurrences | One
Parent elements | (No parent elements)
Child elements | xsl:attribute-set, xsl:import, xsl:include, xsl:output, xsl:param, xsl:template, xsl:variable, msxsl:script

Remarks

A synonym for the <xsl:stylesheet> element. This element can have a set of <xsl:template> elements representing different output templates. Processing begins by processing the root template, indicated by the pattern "/".

Example

This stylesheet outputs a text string, and begins with <xsl:transform> rather than <xsl:stylesheet>.

XML File (mymin.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="helloxslt.xsl"?>
<myelem/>

XSLT File (helloxslt.xsl)

<?xml version='1.0'?>
<xsl:transform version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template match="/">
   <html>
      <body><p>Hello from XSLT!</p></body>
   </html>
</xsl:template>

</xsl:transform>

Formatted Output

Hello from XSLT!

Processor Output

<html>
<body><p>Hello from XSLT!</p></body>
</html>

See Also

xsl:stylesheet Element


xsl:value-of Element

Inserts the value of the selected node as text.

<xsl:value-of
  select = expression
  disable-output-escaping = "yes" | "no"
</xsl:value-of>

Attributes

select
Required. Expression to be evaluated against the current context. The results are converted to a string as by a call to the string() function. A node-set is converted to a string by inserting the string value of the first node in the set.
disable-output-escaping
Default is "no". If the value is "yes", a text node generated by instantiating the <xsl:value-of> element will be output without any escaping. For example, the following generates the single character "<".
<xsl:value-of disable-output-escaping="yes" select="&lt"/>
Note disable-output-escaping="yes" can be used to generate non-well-formed documents, and thus should be used with caution, because non-well-formed output may generate errors in certain circumstances. For example, transformNodeToObject to an XML document requires that the result be well-formed and thus may not complete if disable-output-escaping has affected the well-formedness of the document. Consider disable-output-escaping="yes" an advanced feature to be used only when the potential dangers are understood.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:attribute, xsl:comment, xsl:copy, xsl:element, xsl:fallback, xsl:for-each, xsl:if, xsl:message, xsl:otherwise, xsl:param, xsl:processing-instruction, xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | (No child elements)

Remarks

The <xsl:value-of> element inserts a text string representing the value of the first element (in document order) specified by the select attribute.

If the XML Path Language (XPath) expression returns more than a single node, the <xsl:value-of> element returns the text of the first node returned (equivalent to the XMLDOMNode object's selectSingleNode method). If the node returned is an element with substructure, <xsl:value-of> returns the concatenated text nodes of that element's subtree with the markup removed.

Example

The following .xsl file creates a <p> element from a "person" element with "given-name" and "family-name" child elements. The <p> element will contain the string-value of the first "given-name" child element of the current node, followed by a space and the string-value of the first "family-name" child element of the current node.

XML File (family.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="family.xsl"?>
<family>
  <person>
    <given-name age="10">Fred</given-name>
    <family-name>Smith</family-name>
  </person>
  <person>
    <given-name age="13">Jill</given-name>
    <family-name>Jones</family-name>
  </person>
</family>

XSLT File (family.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="person">
  <p>
    <xsl:value-of select="given-name"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="family-name"/>
  </p>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Fred Smith

Jill Jones

Processor Output

<?xml version="1.0" encoding="UTF-16"?>
  <p>Fred Smith</p>
  <p>Jill Jones</p>

See Also

Creating and Populating an HTML Template | selectSingleNode Method


xsl:variable Element

Specifies a value bound in an expression.

<xsl:variable
  name = Qname
  select = expression>
</xsl:variable>

Attributes

name
Required. Specifies the name of the variable.
select
The value of the attribute is an expression, and the value of the variable is the object that results from evaluating the expression. When this attribute is specified, the content of <xsl:variable> must be empty.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:attribute, xsl:comment, xsl:copy, xsl:element, xsl:for-each, xsl:if, xsl:otherwise, xsl:param, xsl:processing-instruction, xsl:stylesheet xsl:template, xsl:variable, xsl:when, xsl:with-param, output elements
Child elements | xsl:apply-templates, xsl:attribute, xsl:call-template, xsl:choose, xsl:comment, xsl:copy, xsl:copy-of, xsl:element, xsl:for-each, xsl:if, xsl:processing-instruction, xsl:text, xsl:value-of, xsl:variable, output elements

Remarks

The value of the variable may be an object of any type that can be returned by an expression. The <xsl:variable> element can specify the value of the variable in three alternative ways:

  • If the element has a select attribute, the value of the attribute must be an expression and the value of the variable is the object that results from evaluating the expression. In this case, the content of the element must be empty.
  • If the element does not have a select attribute and has non-empty content such as one or more child nodes, the content specifies the value. The content is a template that is instantiated to give the value of the variable. The value is a result-tree fragment equivalent to a node-set containing just a single root node having as children the sequence of nodes produced by instantiating the template. The base URI of the nodes in the result-tree fragment is the base Uniform Resource Identifier (URI) of the variable-binding element.

    An error occurs if a member of the sequence of nodes created by instantiating the template is an attribute node or a namespace node, because a root node cannot have an attribute node or a namespace node as a child.

  • If the content is empty and does not have a select attribute, the value of the variable is an empty string. Thus
    <xsl:variable name="x"/>

    is equivalent to

    <xsl:variable name="x" select="''"/>
    Note When a variable is used to select nodes by position, be careful not to do the following.

    <xsl:variable name="n">2</xsl:variable>
    ...
    <xsl:value-of select="item[$n]"/>
    This will output the value of the first item element, because the variable "n" will be bound to a result-tree fragment, not a number. Instead, do either

    <xsl:variable name="n" select="2"/>
    ...
    <xsl:value-of select="item[$n]"/>
    or

    <xsl:variable name="n">2</xsl:variable>
    ...
    <xsl:value-of select="item[number($n)]"/>
    Note The following is a convenient way to specify the empty node-set as the default value of a parameter.

    <xsl:param name="x" select="/.."/>

Example

This example shows defining a variable based on the values of other variables.

XML File (books.xml)

Use the Sample XML File (books.xml). Below the line <?xml version='1.0'?>, add the following line:

<?xml-stylesheet type="text/xsl" href="sample.xsl"?>

XSLT File (sample.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template match="/">
   <html>
   <body>
      <xsl:variable name="bookCount" select="count(//book)"/>
      <xsl:variable name="bookTotal" select="sum(//book/price)"/>
      <xsl:variable name="bookAverage" select="$bookTotal div $bookCount"/>

      <table border="1">
         <tr>
            <td>
               <b>Title</b>
            </td>
            <td>
               <b>Price</b>
            </td>
            <td>
               <b>Average</b>
            </td>
            <td>
               <b>Difference</b>
            </td>
         </tr>

         <xsl:for-each select="//book">
            <tr>
               <td>
                  <xsl:value-of select="title"/>
               </td>
               <td align="right">
                  <xsl:value-of select="price"/>
               </td>
               <td align="right">
                  <xsl:value-of select="format-number($bookAverage, '#.00')"/>
               </td>
               <td align="right">
                  <xsl:value-of select="format-number(price - $bookAverage, '#.00')"/>
               </td>
            </tr>
         </xsl:for-each>

      </table>
   </body>
   </html>
</xsl:template>

</xsl:stylesheet>

Formatted Output

See Also

xsl:param Element


xsl:when Element

Provides multiple conditional testing in conjunction with the <xsl:choose> and <xsl:otherwise> elements.

<xsl:when
  test = boolean expression>
</xsl:when>

Attributes

test
Required. The condition in the source data to test. If the expression in this attribute evaluates to True when cast to a Boolean, the content of <xsl:when> is instantiated and placed in the output. Node-sets are cast to a Boolean True if they contain at least one node.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:choose
Child elements | xsl:apply-templates, xsl:attribute, xsl:call-template, xsl:choose, xsl:comment, xsl:copy, xsl:copy-of, xsl:element, xsl:for-each, xsl:if, xsl:processing-instruction, xsl:value-of, xsl:variable, output elements

Remarks

Describes one of the alternatives to be chosen by the <xsl:choose> element. The default alternative is described by the <xsl:otherwise> element.

For simple conditional testing, use the <xsl:if> element.

Example

See the example in xsl:choose.

See Also

Defining Conditional Templates Using <xsl:if> and <xsl:choose> | xsl:otherwise Element | xsl:if Element


xsl:with-param Element

Passes a parameter to a template.

<xsl:with-param
  name = Qname
  select = expression>
</xsl:with-param>

Attributes

name
Required. Specifies the name of the parameter.
select
An expression to be matched against the current context. There is no default value. An empty string is generated if there is no content.

Element Information

Number of occurrences | Unlimited
Parent elements | xsl:call-template, xsl:apply-templates
Child elements | xsl:apply-templates, xsl:attribute, xsl:call-template, xsl:choose, xsl:comment, xsl:copy, xsl:copy-of, xsl:element, xsl:for-each, xsl:if, xsl:processing-instruction, xsl:text, xsl:value-of, xsl:variable

Remarks

The name attribute is required. It specifies the name of the parameter. The parameter is the variable the value of whose binding is to be replaced.

The <xsl:with-param> element is allowed within both <xsl:call-template> and <xsl:apply-templates>.

The value of the parameter is specified in the same way as for <xsl:variable> and <xsl:param>.

The current node and current node-list used for computing the value specified by the <xsl:with-param> element is the same as that used for the <xsl:apply-templates> or <xsl:call-template> element within which it occurs.

If you pass a parameter x to a template that does not have an <xsl:param> element for x, this is not an error; the parameter is simply ignored.

Example

A style sheet can use the following approach to call localized message strings.

The messages for a language somelanguage are stored in an XML file, resources/languageabbreviation.xml, in the form shown in the sample XML file below.

To run this sample, view app.xml in Internet Explorer.

XML File (app.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="showlocmsg.xsl" ?>
<showmsg>
   <msg23/>
</showmsg>

XML Resource File (resources/en.xml)

<?xml version='1.0'?>
<messages>
  <message name="msg23">Error 23: The drive is full.</message>
  <message name="msg42">Error 42: The file is not found.</message>
</messages>

XSLT File (showlocmsg.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- these 2 elements effectively assign
     $messages = resources/en.xml/<messages>,
     then $messages is used in the "localized-message" template  -->
<xsl:param name="lang">en</xsl:param>
<xsl:variable name="messages"
      select="document(concat('resources/', $lang, '.xml'))/messages"/>

<xsl:template name="msg23" match="msg23">
  <xsl:call-template name="localized-message">
    <xsl:with-param name="msgcode">msg23</xsl:with-param>
  </xsl:call-template>
</xsl:template>

<xsl:template name="localized-message">
  <xsl:param name="msgcode"/>
  <!-- show message string -->
  <xsl:message terminate="yes">
    <xsl:value-of select="$messages/message[@name=$msgcode]"/>
  </xsl:message>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

<?xml version="1.0" encoding="UTF-16"?>

See Also

xsl:call-template Element | xsl:variable Element | xsl:param Element | xsl:template Element | <xsl:with-param> in the XSLT Samples Viewer

Other Resources Other Resources

XSLT Samples Viewer


XSLT Functions

The XML Path Language (XPath) syntax supports functions to provide information about nodes in a collection. These functions return strings or numbers and can be used with comparison operators in filter patterns. These functions are not available from the selectNodes method in the Document Object Model (DOM).

XSLT Functions

current | Returns a node set that has the current node as its only member.
document | Provides a way to retrieve other XML resources from within the XSL Transformations (XSLT) style sheet beyond the initial data provided by the input stream.
element-available | Returns True if and only if the expanded-name is the name of an instruction.
format-number | Converts the first argument to a string using the format pattern string specified by the second argument.
function-available | Returns True if the function is available in the function library.
generate-id | Returns a string that uniquely identifies the node in the node-set argument that is first in document order.
key | Retrieves elements previously marked with an xsl:key statement.
node-set | Converts a tree into a node set. The resulting node always contains a single node and the root node of the tree.
system-property | Returns an object representing the value of the system property identified by the name.
unparsed-entity-uri | Returns declarations of unparsed entities in the document type definition (DTD) of the source document.

The following are node tests, not functions:

text()
processing-instruction()
comment()
node()

For more information, see Node Tests, Constructing the Node-Test Portion of a Location Step, or Constructing the Node-Test Portion of an XPath Expression.


current Function

Returns a node set that has the current node as its only member.

node-set current()

Remarks

The function returns a node set that has the current node as its only member. For an outermost expression, an expression not occurring within another expression, the current node is always the same as the context node. Thus,

<xsl:value-of select="current()"/>

is the same as

<xsl:value-of select="."/>

However, within square brackets, the current node is usually different from the context node. For example,

<xsl:apply-templates select="//glossary/item[@name=current()/@ref]"/>

processes all <item> elements that have a <glossary> parent element and a name attribute with value equal to the value of the current node's ref attribute. This is different from

<xsl:apply-templates select="//glossary/item[@name=./@ref]"/>

which means the same as

<xsl:apply-templates select="//glossary/item[@name=@ref]"/>

and so would process all <item> elements that have a <glossary> parent element and that have a name attribute and a ref attribute with the same value.

See Also

Data types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


document Function

Provides a way to retrieve other XML resources from within the XSL Transformations (XSLT) style sheet beyond the initial data provided by the input stream.

node-set document(object, node-set?)

Remarks

The document() function is versatile. Its effects vary, depending on the type and number of arguments that are used.

  • If only one argument is provided and that argument is a string, then document() treats the string as a URL and retrieves the document as a set of nodes.
  • If only one argument is provided and that argument is a node set, then each node in that node set is treated as a URL and the function returns the union of all of the documents referenced.
  • If there are two arguments, the first argument can be either a string or a node set while the second argument must be a node set. The second argument, when supplied, serves to indicate the base URL to which the contents of the first argument are relative.
  • If an empty string is passed to the document() function, the result is the source XML of the XSLT document itself, unless the second argument is given (and is not null). In the latter case, the URL of the document is the base URL of the node contained in the second element.

Example

The following style sheet generates a document containing the employee nodes in all of the referenced documents.

XML File (empref.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="docfn.xsl" ?>
<employeeRefs>
   <employeeDoc href="http://www.microsoft.com/employees/employeeList.xml"/>
   <employeeDoc href="localEmployees1.xml"/>
   <employeeDoc href="localEmployees2.xml"/>
</employeeRefs>

XSLT File (docfn.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <employees>
        <xsl:apply-templates select="//employeeDoc"/>
    </employees>
</xsl:template>

<xsl:template match="employeeDoc">
    <xsl:copy-of select="document(@href)//employee"/>
</xsl:template>

</xsl:stylesheet>

See Also

xsl:copy-of Element


element-available Function

Returns True only if the expanded-name is the name of an instruction.

boolean element-available(string)

Remarks

The argument must evaluate to a string that is a QName. The QName is expanded into an expanded-name using the namespace declarations in scope for the expression. This function returns True for all XSL Transformations (XSLT) elements supported in this release and False for each XSLT element not supported in this release. In addition, it returns True for all extension elements supported in this release, currently only msxsl:script. Outside of XSLT, it will always return False.

Example

The following function call returns True (provided the xsl prefix is mapped to the XSLT namespace).

element-available("xsl:template")

See Also

Data types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


format-number Function

Converts numbers into strings. The conversion is the result of formatting the number specified in the first argument (number), using the format specified in the second argument (string), and applying the rules defined in the decimal format named in the third optional argument (string). If the third argument, the decimal format name, is omitted, the default decimal format is used. This function and the <xsl:decimal-format> element are designed to be used together.

string format-number(number, string, string?)

Remarks

The first argument specifies the input value. For example, the number 5351.

The second argument specifies the format pattern. For example, the string '###.###,00'.

The third argument is an optional decimal format name. This enables any character to be used in the format pattern string; the character is assigned a role in the <xsl:decimal-format> element. A common decimal format name is 'european', used to reverse the role of comma and period from the default.

In the format pattern, the following characters are supported "."; ","; "#","%","0", and the Unicode per-mille character (#x2030). The "#" character is used to describe integers. The "." and "," characters are used to describe the location and type of punctuation. The "0" character is used to place a 0 before and after the "." character when the position would otherwise show no numeral, such as 00.3 or 3.00. When truncating digits to the right of the decimal points, the number is rounded. The number to the left of the decimal point is never truncated.

The input value and format pattern string must both be present or an error will be thrown. If the input value cannot be coerced to a number by using the rules in the number() function, the format-number function returns NaN. If the format pattern string is not a valid pattern string, the function returns the input value, unchanged.

The decimal format name, if present, represents the name of a decimal format as specified in an <xsl:decimal-format> element. The decimal format name must be a qualified name. If you specify a decimal format name in the function, there must be an <xsl:decimal-format> element in the stylesheet with the same name.

The <xsl:decimal-format> element can override the default number formatting pattern. The <xsl:decimal-format> element follows the formatting specifier patterns of the java.text.DecimalFormat class. For examples of using the format-number function with xsl:decimal-format, see xsl:decimal-format Element.

Examples

The following function call returns "5,351":

format-number(5351,"#,###")

The following function call returns "5351.00":

format-number(5351, "#.00")

The following function call returns "53.5100":

format-number(53.51, "#.0000")

The following function call returns "0053.5100":

format-number(53.51, "0000.0000")

The following function call returns "0053.51":

format-number(53.51, "0000.####")

The following function call returns "53.6":

format-number(53.56, "0.0")

The following XSL lines return "24.535,20":

<xsl:decimal-format name="european" decimal-separator=',' grouping-separator='.' />
<xsl:value-of select="format-number(24535.2, '###.###,00', 'european')"/>

See Also

Data types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD) | <xsl:decimal-format> Element


function-available Function

Returns True if the function is in the function library.

boolean function-available(string)

Remarks

The argument must evaluate to a string that is a QName. The QName is expanded into an expanded-name using the namespace declarations in scope for the expression. The function-available function returns True if and only if the expanded-name is the name of a function in the function library. If the expanded-name has a non-null namespace Uniform Resource Identifier (URI), it refers to an extension function; otherwise, it refers to a function defined by XML Path Language (XPath) or XSL Transformations (XSLT).

Example

The following function call returns True.

function-available("format-number")

See Also

Data types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


generate-id Function

Returns a string that uniquely identifies the node in the node-set argument that is first in document order.

string generate-id(node-set?)

Remarks

The unique identifier must consist of ASCII alphanumeric characters and must start with an alphabetic character. Thus, the string is syntactically an XML name. There is no guarantee that a generated unique identifier will be distinct from any unique IDs specified in the source document. If the node-set argument is empty, the empty string is returned. If the argument is omitted, it defaults to the context node.

Example

XML File (data.xml)

<?xml-stylesheet type="text/xsl" href="sample.xsl"?>
<catalog>
    <book id="bk101">
        <author>Gambardella, Matthew</author>
        <title>XML Developer's Guide</title>
        <genre>Computer</genre>
        <price>44.95</price>
        <publish_date>2000-10-01</publish_date>
        <description>An in-depth look at creating applications with XML.</description>
    </book>
    <book id="bk102">
        <author>Ralls, Kim</author>
        <title>Midnight Rain</title>
        <genre>Fantasy</genre>
        <price>5.95</price>
        <publish_date>2000-12-16</publish_date>
        <description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description>
    </book>
</catalog>

XSLT File (sample.xsl)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html"/>
  <xsl:template match="/">
        <html>
            <body>
                <xsl:for-each select="//book">
                    <button id="{generate-id(author)}" onclick="alert(this.id)">
                        <xsl:value-of select="author"/>
                    </button>
                </xsl:for-each>
            </body>
        </html>
  </xsl:template>
</xsl:stylesheet>

Formatted Output

When you click the left button in Internet Explorer, an alert box displays "IDAHAGJD".

When you click the right button in Internet Explorer, an alert box displays "IDAPAGJD".

Processor Output

<html>
<body><button id="IDAHAGJD" onclick="alert(this.id)">Gambardella, Matthew</button>
<button id="IDAPAGJD" onclick="alert(this.id)">Ralls, Kim</button></body>
</html>

See Also

Data types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


key Function

Retrieves elements previously marked with an xsl:key statement.

node-set key(name, value)

Remarks

The key() function retrieves a node set (zero or more nodes) that have the same key name and key value specified in the <xsl:key> statement. When the XSL Transformations (XSLT) style sheet is first processed, the keys are stored internally to simplify access. Keys can simplify accessing nodes in the XML document, but may not be faster than using XML Path Language (XPath) to retrieve the same nodes.

Example

The key() function works in conjunction with the xsl:key element. For an example, see xsl:key Element.

See Also

xsl:key Element


node-set Function

Enables you to convert a tree into a node set. The resulting node always contains a single node and the root node of the tree.

msxsl:node-set(string)

Remarks

With earlier versions of the Microsoft® XML Parser (MSXML), it was possible to use expressions such as <xsl:for-each select="$var/el">, where var is an XSL Transformations (XSLT) variable bound to a result tree. However, this approach does not work with MSXML 3.0. To achieve the same results, use the node-set function, as shown in the following code sample.

<xsl:for-each select="msxsl:node-set($var)/el)">

See Also

Data types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


system-property Function

Returns an object representing the value of the system property identified by the name.

object system-property(string)

Remarks

The argument must evaluate to a string that is a valid QName. The QName is expanded into a name using the namespace declarations in scope for the expression. The system-property function returns an object representing the value of the system property identified by the name. If there is no such system property, the empty string is returned.

Because these properties are strings representing QNames, a prefix must correspond to a namespace declaration in scope for "http://www.w3.org/1999/XSL/Transform" for the xsl:version, xsl:vendor, and xsl:vendor-url properties. A prefix corresponding to a namespace declaration "urn:schemas-microsoft-com:xslt" must be in scope for the msxsl:version property.

System property | Description
xsl:version | A number giving the version of XSL Transformations (XSLT) implemented by the processor; for XSLT processors implementing the version of XSLT specified by this document, the number 1.
xsl:vendor | Returns the string "Microsoft".
xsl:vendor-url | A string containing the URL "http://www.microsoft.com".
msxsl:version | A number giving the version of the Microsoft XML Parser (MSXML). 3 for this release.

Example

The following function call returns 1.

system-property('xsl:version')

See Also

Data types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


unparsed-entity-uri Function

Provides access to declarations of unparsed entities in the document type definition (DTD) of the source document. It returns the empty string if there is no such entity.

string unparsed-entity-uri(string)

Remarks

If the document containing the context node includes an unparsed entity that is specified in the string parameter of the unparsed-entity-uri() function, then a Uniform Resource Identifier (URI) identifying that unparsed entity is returned. If there is no entity with this name, an empty string is returned.

Example

This example demonstrates the unparsed-entity-uri() function.

XML File (data.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="sample.xsl"?>
<!DOCTYPE catalog [
<!ELEMENT catalog ANY>
<!ELEMENT book ANY>
<!ELEMENT title ANY>
<!NOTATION JPEG SYSTEM "urn:foo">
<!ENTITY pic SYSTEM "somepic.jpg" NDATA JPEG>
]>
<catalog>
<book>
    <title>XML Developer's Guide</title>
</book>
<book>
    <title>Midnight Rain</title>
</book>
</catalog>

XSLT File (sample.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template match="/">
   <html>
      <body>
         <h3>unparsed-entity-uri()</h3>
         <ul>
            <li>
               <b>unparsed-entity-uri('pic')</b> =
               <xsl:value-of select="unparsed-entity-uri('pic')"/>
            </li>
         </ul>
      </body>
   </html>
</xsl:template>

</xsl:stylesheet>

Formatted Output

unparsed-entity-uri()

  • unparsed-entity-uri('pic') = file:///C:/XML UE/XML SDK/Source/XSLTDevGuide/Samples/ref/test2/somepic.jpg

Processor Output

<html>
<body>file:///C:/Projects/XSLTExamples/XSLTFunctions/unparsed-entity-uri/somepic.jpg</body>
</html>

See Also

Data types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


XSLT Syntax

This section covers the following:

  • Qualified Names
  • NaN Values
  • Expressions
  • Patterns


Qualified Names

A qualified name (QName) is composed of a prefix and a local part. The prefix provides the namespace prefix part of the qualified name, and must be associated with a namespace Uniform Resource Identifier (URI).

Note The prefix functions only as a placeholder for a namespace name. Applications should use the namespace name, not the prefix, in constructing names whose scope extends beyond the containing document.


NaN Values

The term NaN, which stands for "not a number," means a symbolic entity that represents a value not otherwise available in floating-point format.

There are two kinds of NaNs.

Quiet
Represent unknown or uninitialized values.
Signaling
Represent symbolic values and values that are too big or too precise for the format. Signaling NaNs raise an invalid operation exception whenever an operation is attempted on them.


Expressions

Expressions are used in XSL Transformations (XSLT) for the following purposes.

  • Selecting nodes for processing.
  • Specifying conditions for different ways of processing a node.
  • Generating text to be inserted in the result tree.

Expressions occur as the value of certain attributes on XSLT-defined elements and within curly braces in attribute value templates.

Expression evaluation occurs with respect to a context. In XSLT, an outermost expression (that is, an expression that is not part of another expression) gets its context as follows.

  • The context node comes from the current node.
  • The context position comes from the position of the current node in the current node list; the first position is 1.
  • The context size comes from the size of the current node list.
  • The variable bindings are the bindings in scope on the element that has the attribute in which the expression occurs.
  • The set of namespace declarations are those in scope on the element that has the attribute in which the expression occurs.
  • The function library consists of those found at XPath Functions and XSLT Functions. It is an error for an expression to include a call to any other function.

See Also

Patterns


Patterns

A pattern is a type of expression that returns a set of nodes based on a set of conditions for a node. Nodes that satisfy the conditions match the pattern. The syntax for patterns is a subset of the syntax for expressions. In particular, location paths that meet certain restrictions can be used as patterns. An expression that is also a pattern always evaluates to an object of type node-set. A node matches a pattern if the node is a member of the result of evaluating the pattern as an expression with respect to some possible context; the possible contexts are those whose context node is the node being matched or one of its ancestors.

The following table lists examples of patterns.

Pattern | Matches
Para | any para element
* | any element
chapter|appendix | any chapter element and any appendix element
olist/item | any item element with an olist parent
appendix//para | any para element with an appendix ancestor element
/ | the root node
text() | any text node
processing-instruction() | any processing instruction
node() | any node other than an attribute node and the root node
id("W11") | the element with unique ID W11
para[1] | any para element that is the first para child element of its parent
*[position()=1 and self::para] | any para element that is the first child element of its parent
para[last()=1] | any para element that is the only para child element of its parent
items/item[position()&gt;1] | any item element that has an items parent and that is not the first item child of its parent
item[position() mod 2 = 1] | any item element that is an odd-numbered item child of its parent
div[@class="appendix"]//p | any p element with a div ancestor element that has a class attribute with value appendix
@class | any class attribute (not any element that has a class attribute)
@* | any attribute

See Also

Location Paths


XPath Reference

XML Path Language (XPath) is a general-purpose query notation for addressing and filtering the elements and text of XML documents. XPath expressions can address parts of an XML document; manipulate strings, numbers, and Booleans; and can match a set of nodes in the document.

The Microsoft® XML Parser (MSXML 4.0) supports XPath within Extensible Stylesheet Language Transformations (XSLT), and through the DOM extensions, selectNodes and selectSingleNode. MSXML 4.0 implements XPath as described in the XML Path Language (XPath) Version 1.0 Recommendation by the Worldwide Web Consortium (W3C). For information about the parser's conformance, see Supported XSLT Features.

XPath models an XML document as a tree of different type nodes. XPath expressions identify these nodes in the XML document based on their type, name, and values, as well as the relationship of a node to other nodes in the document. An XPath expression yields one of the following basic objects.

  • node set
  • Boolean
  • number
  • string

For example, the query "find the author elements that have a period attribute with the value of 'classical', and that are contained in the authors element at the document root" can be expressed as in XPath expression as "/authors/author[@period='classical']".

This section covers the following:

  • XPath Syntax
  • XPath Functions

See Also

  • Introduction to XPath Syntax
  • Introduction to the XPath Tree Model
  • Basic Syntax of XPath Expressions
  • Differences between XPath Expressions and XSLT Patterns
  • Context and Navigation in XPath
  • Working with Lists of Items Using XPath
  • Using XPath Axes to Navigate through XML Data
  • Filtering XML Data Using XPath Predicates
  • Using Functions in XPath Expressions
  • Constructing Complex XPath Searches

Other Resources Other Resources

XML Path Language (XPath) Version 1.0 (W3C Recommendation 16 November 1999)


XPath Syntax

This section covers the syntax of XPath expressions, including the following:

  • Overview of XPath Expression Syntax
  • Operators and Special Characters
  • Collections
  • Filters and Filter Patterns
  • Boolean, Comparison, and Set Expressions
  • Comparisons
  • Set Operations
  • Location Paths
  • XPath Examples

Topics in this section use the Sample XML File for XPath Syntax (inventory.xml).


Sample XML File for XPath Syntax (inventory.xml)

This XML file is used by some topics in the XPath Reference documentation. This file represents a fragment of a bookstore inventory database.

XML File (inventory.xml)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="myfile.xsl" ?>
<bookstore specialty="novel">
  <book style="autobiography">
    <author>
      <first-name>Joe</first-name>
      <last-name>Bob</last-name>
      <award>Trenton Literary Review Honorable Mention</award>
    </author>
    <price>12</price>
  </book>
  <book style="textbook">
    <author>
      <first-name>Mary</first-name>
      <last-name>Bob</last-name>
      <publication>Selected Short Stories of
        <first-name>Mary</first-name>
        <last-name>Bob</last-name>
      </publication>
    </author>
    <price>55</price>
  </book>
  <magazine style="glossy" frequency="monthly">
    <price>2.50</price>
    <subscription price="24" per="year"/>
  </magazine>
  <book style="novel" id="myfave">
    <author>
      <first-name>Toni</first-name>
      <last-name>Bob</last-name>
      <degree from="Trenton U">B.A.</degree>
      <degree from="Harvard">Ph.D.</degree>
      <award>Pulitzer</award>
      <publication>Still in Trenton</publication>
      <publication>Trenton Forever</publication>
    </author>
    <price intl="Canada" exchange="0.7">6.50</price>
    <excerpt>
      <p>It was a dark and stormy night.</p>
      <p>But then all nights in Trenton seem dark and
      stormy to someone who has gone through what
      <emph>I</emph> have.</p>
      <definition-list>
        <term>Trenton</term>
        <definition>misery</definition>
      </definition-list>
    </excerpt>
  </book>
  <my:book xmlns:my="uri:mynamespace" style="leather" price="29.50">
    <my:title>Who's Who in Trenton</my:title>
    <my:author>Robert Bob</my:author>
  </my:book>
</bookstore>

See Also

XPath Examples | XPath Syntax


Overview of XPath Expression Syntax

XML Path Language (XPath) uses a declarative notation rather than a procedural one. Each expression developed from this notation describes the types of nodes to match based on the hierarchical relationship between the nodes. For example, the expression "book/author" means find the author elements contained in book elements.

This notation enables you to query an XML document tree, which represents the contents of an XML document, as a hierarchy of nodes. The syntax mimics the Uniform Resource Identifier (URI) directory navigation syntax. However, instead of specifying navigation through a logical hierarchy of directories, the navigation is through a hierarchy of nodes in the XML tree.

Context for XPath Expressions

All XPath expressions occur within a particular context, that is, the single node against which the expression operates. To understand the concept of context, consider a tree containing nodes. Asking for all nodes named X from the root of the tree returns one set of results, while asking for those nodes from a branch in the tree returns a different set of results. The result of an expression depends on the context against which it is executed.

XPath expressions can match specific patterns at one particular context, retrieve the results, and perform additional operations relative to the context of the returned nodes. This gives XPath expressions extraordinary flexibility in searching throughout the document tree.

When using expressions with the Microsoft XML Document Object Model (DOM) programming interfaces, the context is the Node object whose selectNodes method or selectSingleNode method is called.

An expression prefixed with a period and forward slash (./) explicitly uses the current context as the context for the query.

An expression prefixed with a forward slash (/) uses the root of the document tree as the context for the query.

An expression can use the double forward slash (//) operator to indicate a search that can include zero or more levels of hierarchy. When this operator appears at the beginning of the pattern, the context is relative to the root of the document. The .// prefix indicates that the context starts at the level in the hierarchy indicated by the current context.

Note Element names can include the period character (.), and these can be used in patterns just as any other name.

Examples

Find the background.jpg file within the images directory:

images/background.jpg

Find the collection of book elements within bookstore elements:

bookstore/book

Find all author elements within the current context:

./author

Note that this is equivalent to the following:

author

Find all first.name elements:

first.name

Find the bookstore element at the root of this document:

/bookstore

Find the root element of this document:

/*

Find all author elements anywhere within the current document:

//author

Find all bookstores where the value of the specialty attribute is equal to "textbooks":

/bookstore[@specialty = "textbooks"]

Find all books where the value of the style attribute on the book is equal to the value of the specialty attribute of the bookstore element at the root of the document:

book[@style = /bookstore/@specialty]

In addition to this notation for representing hierarchical relationships among nodes, the implementation also supports the following:

  • Boolean, Comparison, and Set Expressions
  • Set Operations
  • Filters and Filter Patterns
  • Collections
  • XPath Functions

XPath also support namespaces and data types. Namespace prefixes can be included in patterns so that the matching operations can check for specific namespace prefixes.

Other Resources Other Resources

XML Path Language (XPath) Version 1.0


Operators and Special Characters

XML Path Language (XPath) expressions are constructed using the operators and special characters shown in the following table.

/ | Child operator; selects immediate children of the left-side collection. When this path operator appears at the start of the pattern, it indicates that children should be selected from the root node.
// | Recursive descent; searches for the specified element at any depth. When this path operator appears at the start of the pattern, it indicates recursive descent from the root node.
. | Indicates the current context.
* | Wildcard; selects all elements regardless of the element name.
@ | Attribute; prefix for an attribute name.
@* | Attribute wildcard; selects all attributes regardless of name.
: | Namespace separator; separates the namespace prefix from the element or attribute name.
( ) | Groups operations to explicitly establish precedence.
[ ] | Applies a filter pattern.
[ ] | Subscript operator; used for indexing within a collection.
+ | Performs addition.
- | Performs subtraction.
div | Performs floating-point division according to IEEE 754.
* | Performs multiplication.
mod | Returns the remainder from a truncating division.

This table does not list Boolean, Comparison, and Set Expressions or Set Operations.

Precedence order (from highest precedence to lowest) is defined as indicated in the following table.

Precedence | Character | Purpose
1 | ( ) | Grouping
2 | [ ] | Filters
3 | / // | Path operations

Note that the filter pattern operators (the brackets) have a higher precedence than the path operators (the slash characters). For example, the expression "//comment()[3]" is interpreted as "//(comment()[3])", and selects all comments with an index equal to 3 relative to the comment's parent anywhere in the document. This differs from the expression "(//comment())[3]", which selects the third comment from the set of all comments relative to the parent. The first expression can return more than one comment, while the latter can return only one comment.

These operators and special characters are described in detail throughout this reference.

Path Operators

The collection of elements of a certain type can be determined using the path operators (/ and //). These operators take as their arguments a "left side" collection on which to perform the selection and a "right side" collection indicating which elements to select. The child operator (/) selects from immediate children of the left-side collection, while the descendant operator (//) selects from arbitrary descendants of the left-side collection. In effect, // can be considered a substitute for one or more levels of hierarchy.

Note that the path operators change the context as the query is performed. By stringing path operators together, users can traverse the document tree.

Examples

Find all first-name elements within an author element. Note that the author children of the current context are found, and then first-name children are found, relative to the context of the author elements:

author/first-name

Find all title elements one or more levels deep in the bookstore (arbitrary descendants):

bookstore//title

Note that this is different from the following pattern, which finds all title elements that are grandchildren of bookstore elements:

bookstore/*/title

Find emph elements anywhere inside book excerpts, anywhere inside the bookstore:

bookstore//book/excerpt//emph

Find all titles one or more levels deep in the current context. Note that this situation is essentially the only one in which the period notation is required.

.//title

Wildcard Character

An element can be referenced without using its name by substituting the wildcard (*) collection. The * collection returns all elements that are children of the current context, regardless of the tag name.

Examples

Find all element children of author elements:

author/*

Find all last names that are grandchildren of books:

book/*/last-name

Find the grandchildren elements of the current context:

*/*

Find the book element from the "my" namespace:

my:book

Find all elements from the "my" namespace:

my:*

Note that the pattern "*:book" is not supported.

Attributes

XPath denotes attribute names with the @ symbol. Attributes and child elements are treated impartially, and capabilities are equivalent between the two types wherever possible.

Note Attributes cannot contain child elements, so syntax errors occur when path operators are applied to attributes. In addition, you cannot apply an index to attributes because, by definition, no order is defined for attributes.

Examples

Find the style attribute of the current element context:

@style

Find the exchange attribute on price elements within the current context:

price/@exchange

The following example is not valid:

price/@exchange/total

Find the style attribute for all book elements:

book/@style

Finding Multiple Attributes

All attributes of an element can be returned using @*. This is potentially useful for applications that treat attributes as fields in a record.

Note that the pattern "@*:title" is not supported.

Examples

Find all attributes of the current element context:

@*

Find all attributes from the "my" namespace. This does not include unqualified attributes on elements from the "my" namespace:

@my:*

See Also

Set Operations | Sample XML File for XPath Syntax (inventory.xml) | XPath Examples


Collections

Collections returned by XML Path Language (XPath) queries preserve document order, hierarchy, and identity, to the extent that these are defined. That is, a collection of elements is returned in document order without repeated elements. Because by definition attributes are unordered, there is no implicit order to attributes returned for a specific element.

The collection of all elements with a certain tag name is expressed using the tag name itself. This can be qualified by showing that the elements are selected from the current context by using a period and forward slash (./), but the current context is used by default and does not have to be noted explicitly.

Examples

Find all first-name elements. These following examples are equivalent.

./first-name
first-name

Find all unqualified book elements.

book

Indexing into a Collection

XPath expressions make it easy to find a specific node within a set of nodes. Simply enclose the index ordinal within square brackets. The ordinal is 1-based (the first element is number 1).

The bracket characters [] have higher precedence than the slash characters / and //. The expression "//comment()[3]" is interpreted as "//(comment()[3])", and selects all comments with an index equal to 3 relative to the comment's parent anywhere in the document. This differs from the expression "(//comment())[3]", which selects the third comment from the set of all comments relative to the parent. The first expressions can return more than one comment, while the other expression can return only one comment.

Examples

The following finds the first author element.

author[1]

The following finds the third author element that has a first name.

author[first-name][3]

Note that indexes are relative to the parent. Consider the following data.

<x>
  <y/>
  <y/>
</x>
<x>
  <y/>
  <y/>
</x>

Find the first y from each x.

x/y[1]

Find the first y from the entire set of y elements within x elements.

(x/y)[1]

Find the first y from the first x.

x[0]/y[1]

Finding the Last Element in a Collection

The last function returns True for the last element in a collection. Note that last is relative to the parent node.

Examples

Find the last book:

book[last()]

Find the last author for each book:

book/author[last()]

Find the last author from the entire set of authors of books:

(book/author)[last()]

Grouping

Parentheses can be used to group collection operators for clarity or where the normal precedence is inadequate to express an operation.

See Also

Sample XML File for XPath Syntax (inventory.xml) | XPath Examples


Filters and Filter Patterns

Constraints and branching can be applied to any collection by adding a filter clause, [pattern], to the collection. The filter is analogous to the SQL WHERE clause. The filter contains a pattern within it called the filter pattern. The filter pattern evaluates to a Boolean value and is tested for each element in the collection. Any elements in the collection failing the filter pattern test are omitted from the result collection.

For convenience, if a collection is placed within the filter, a Boolean TRUE is generated if the collection contains any members and a FALSE is generated if the collection is empty. An expression such as "author/degree" implies a collection-to-Boolean conversion function that evaluates to TRUE if there exists an author with a child element degree.

Note that any number of filters can appear at a given level of an expression. Empty filters are not allowed.

Filters are always evaluated with respect to a context. In other words, the expression "book[author]" means that for every book element that is found, test whether it has an author child element. Likewise, "book[author = 'Bob']" means that for every book element that is found, test whether it has an author child element with the value "Bob". One can examine the value of the context as well by using the period (.) character. For example, "book[. = 'Trenton']" means that for every book that is found in the current context, test whether its value is "Trenton".

If a filter compares values of elements and the filter is to be applied to more than one child element, you might want to use the any and all keywords. When these keywords are not specified, only the first matching child is used for the comparison.

This pattern looks for the first author child of each book element. If the value of the author child is "Bob", the corresponding book element will be returned:

book[author="Bob"]

Examples

Find all books that contain at least one excerpt element:

book[excerpt]

Find all titles of books that contain at least one excerpt element:

book[excerpt]/title

Find all authors of books where the book contains at least one excerpt and the author has at least one degree:

book[excerpt]/author[degree]

Find all books that have authors with at least one degree:

book[author/degree]

Find all books that have an excerpt and a title:

book[excerpt][title]

See Also

Sample XML File for XPath Syntax (inventory.xml) | XPath Examples


Boolean, Comparison, and Set Expressions

Filter patterns can contain Boolean expressions, comparison expressions, and set expressions. Shortcuts listed in the following table represent alternative symbols that are provided in this XSL Transformations (XSLT) implementation. This documentation discusses these expression operators.

Operator | Description
and | Logical-and
or | Logical-or
not() | Negation
= | Equality
!= | Not equal
&lt; * | Less than
&lt;= * | Less than or equal
&gt; * | Greater than
&lt;= * | Greater than or equal
| | Set operation; returns the union of two sets of nodes

* extended XPath method

The Worldwide Web Consortium (W3C) syntax for operator keywords uses white space and other separators rather than the dollar sign character ($) used in version 2.5. In the W3C syntax, a binary keyword of the form $xxx$ can be expressed as wsxxxws, where ws refers to a token terminator that can be white space, single quote characters ('), or double quote characters ("). Unary operators such as not() use functional notation. Although the Microsoft implementation supports both syntaxes, it is recommended that the W3C syntax be used for future compatibility.

Precedence order (from highest to lowest) for comparison operators and Boolean operators is shown in the following table.

1 | ( ) | Grouping
2 | [ ] | Filters
3 | / // | Path operations
4 | &lt; &lt;= &gt; &gt;= | Comparisons
5 | = != | Comparisons
6 | | | Union
7 | not() | Boolean not
8 | and | Boolean and
9 | or | Boolean or

Boolean expressions can match all nodes of a particular value or all nodes with nodes in particular ranges. Boolean expressions are in the form (left-side value operator right-side value) and return a Boolean result.

Operators are case-sensitive.

Boolean AND and OR

The Boolean operators and and or perform logical-and and logical-or operations, respectively. These operators, in conjunction with grouping parentheses, can be used to build sophisticated logical expressions.

Examples

Find all author elements that contain at least one degree and one award:

author[degree and award]

Find all author elements that contain at least one degree or award and at least one publication:

author[(degree or award) and publication]

Boolean NOT

The Boolean not operator negates the value of an expression within a filter pattern.

Examples

Find all author elements that contain at least one degree element and contain no publication elements:

author[degree and not(publication)]

Find all author elements that contain publication elements but do not contain either degree elements or award elements:

author[not(degree or award) and publication]

See Also

Sample XML File for XPath Syntax (inventory.xml) | XPath Examples


Comparisons

The = sign is used for equality; != is used for inequality.

Two operands are supplied for a comparison operation: the vector or scalar that is to be compared (the left-side value, or lvalue) and the scalar value (the right-side value, or rvalue) against which to compare. The rvalue must either be a scalar or a value that can be cast at run time to a scalar.

If the lvalue of a comparison is a set, "any" semantics are used for the comparison operators. That is, the result of a comparison is True if any item in the set meets the condition.

The lvalue of an expression cannot be a literal. For example, "3" = a is not allowed. If the rvalue is an attribute, the text(lvalue) is compared to the text(rvalue).

All elements and attributes are strings but are automatically cast as integer values for numeric comparisons. Literal numeric values are cast to long or double types during comparison operations, as shown in the following table.

Literal type | Comparison | Example
String | text(lvalue) op text(rvalue) | a &lt; GGG
Integer | (long) lvalue op (long) rvalue | a &lt; 3
Real | (double) lvalue op (double) rvalue | a &lt; 3.1

Only XSL patterns support the string comparison operators "<", ">", ">=" and "<=", not XPath/XSLT. In other words, when you call selectNodes() in DOM and set "SelectionLanguage" to 'XSLPattern"(by default), the above string comparison operators will work. Only "=" and "!=" operators may be used in XPath/XSLT.

Single or double quotation marks can be used for string delimiters in expressions. This makes it easier to construct and pass patterns from within scripting languages.

Examples

Find all author elements whose last name is Bob:

author[last-name = "Bob"]

Find all author elements where the first last-name is Bob:

author[last-name[1] = "Bob"]

Find all authors where the from attribute is not equal to "Harvard":

author/degree[@from != "Harvard"]

Find all authors where the last name is the same as the /guest/last-name element:

author[last-name = /guest/last-name]

Find all authors whose text is "Matthew Bob":

author[. = "Matthew Bob"]

Order of Precedence for Comparisons

Comparisons with regard to data types obey the order of precedence.

  • If at least one operand is a Boolean, each operand is first converted to a Boolean.
  • Otherwise, if at least one operand is a number, each operand is first converted to a number.
  • Otherwise, if at least one operand is a date, each operand is first converted to a date.
  • Otherwise, both operands are first converted to strings.

Comparing Dates

If one operand is a node-set and the other is a date, the comparison will be True if and only if there is a node in the node-set operand such that the result of performing the comparison on the date operand and on the result of converting the value of that node to a date using the msxslt:date() function is True.

Two dates are equal only if an unambiguous canonical format for the date (for example, GMT representation as a number) indicates that they are so.

A date is less than another date if it indicates a date/time earlier than the second date/time, and so on.

Binary Comparison Operators

A set of binary comparison operators compares numbers and strings and returns Boolean results. &lt;, &lt;=, &gt;, and &gt;= are used for less than, less than or equal, greater than, and greater than or equal. Single or double quotation marks can be used for string delimiters in expressions. This makes it easier to construct and pass patterns within scripting languages.

Examples

Find all author elements whose last name is "Bob" and whose price is > 50:

author[last-name = "Bob" and price &gt; 50]

Find all authors where the from attribute is not equal to "Harvard":

degree[@from != "Harvard"]

Find all authors whose last name begins with "M" or greater:

author[last-name &gt;= "M"]

Find the first three books (1, 2, 3):

book[position() &lt;= 3]

Example

XML File (books.xml)

Use the Sample XML File for XPath Syntax (inventory.xml) and change the href attribute to reference xpcompare.xsl.

XSLT File (xpcompare.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="//book">
   <p/>author[last-name = "Bob"] --
      <xsl:value-of select='author[last-name = "Bob"]'/>
   <p/>author[last-name[1] = "Bob"] --
      <xsl:value-of select='author[last-name[1] = "Bob"]'/>
   <p/>author/degree[@from != "Harvard"] --
      <xsl:value-of select='author/degree[@from != "Harvard"]'/>
   <p/>author[last-name = /guest/last-name] --
      <xsl:value-of select='author[last-name = /guest/last-name]'/>
   <p/>author[. = "Matthew Bob"] --
      <xsl:value-of select='author[. = "Matthew Bob"]'/>
   <p/>author[last-name = "Bob" and price &gt; 50] --
      <xsl:value-of select='author[last-name = "Bob" and price &gt; 50]'/>
   <p/>degree[@from != "Harvard"] --
      <xsl:value-of select='degree[@from != "Harvard"]'/>
   <p/>author[last-name &gt;= "M"] --
      <xsl:value-of select='author[last-name &gt;= "M"]'/>
   <p/>book[position() &lt;= 3] --
      <xsl:value-of select='book[position() &lt;= 3]'/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

This example doesn't generate significant output. It simply demonstrates that no errors are generated by the above XPath expressions.

See Also

Sample XML File for XPath Syntax (inventory.xml) | XPath Examples


Set Operations

XML Path Language (XPath) supports the set operation |.

"|" Operator

The "|", or union, operator returns the union of two queries; that is, it returns the set of nodes returned for one query combined with the set of nodes that satisfy the other query. Multiple union operators can be combined to union together the results of multiple queries. The union operator preserves document order and does not return duplicates.

The Microsoft implementation extends the union operator to be available anywhere in a query, not just at the top level. To support this behavior, the following constraint is applied to unions: All queries combined with the union operator must be from the same subtree and have the same root.

The following table demonstrates examples of valid and invalid queries based on these constraints:

Valid use of | (same subtree) | Invalid use of | (different subtrees)
a | b | c | a | /b | c
/a | /b | /c | a | /b | c
a | . | a | id('C1')
a | b | a | ../b
a | b | a | current()/b
id(x | y) | id(x) | id(y)

Examples

Find all first-names and last-names:

first-name | last-name

Find all books and magazines from a bookstore:

bookstore/(book | magazine)

Find all books and all authors:

book | book/author

Find the first-names, last-names, or degrees from authors within either books or magazines:

(book | magazine)/author/(first-name | last-name | degree)

Find all books with author/first-name equal to "Bob" and all magazines with price less than 10:

book[author/first-name = "Bob"] | magazine[price &lt; 10]

The following will return the first node that matches, not multiple nodes:

id(x | y)

Precedence

Precedence order (from highest precedence to lowest) between Boolean and comparison operators is shown in the following table.

1 | ( ) | Grouping
2 | [ ] | Filters
3 | / // | Path operations
4 | &lt; &lt;= &gt; &gt;= | Comparisons
5 | = != | Comparisons
6 | | | Union
7 | not() | Boolean not
8 | and | Boolean and
9 | or | Boolean or

Example

XML File (books.xml)

Use the Sample XML File for XPath Syntax (inventory.xml) and change the href attribute to reference xpsetops.xsl.

XSLT File (xpsetops.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="//book">
   <p/>first-name | last-name --
      <xsl:value-of select='first-name | last-name'/>
   <p/>bookstore/(book | magazine) --
      <xsl:value-of select='bookstore/(book | magazine)'/>
   <p/>book | book/author --
      <xsl:value-of select='book | book/author'/>
   <p/>(book | magazine)/author/(first-name | last-name | degree) --
      <xsl:value-of select='(book | magazine)/author/(first-name | last-name | degree)'/>
   <p/>book[author/first-name = "Bob"] | magazine[price &lt; 10] --
      <xsl:value-of select='book[author/first-name = "Bob"] | magazine[price &lt; 10]'/>
   <p/>id(x | y) --
      <xsl:value-of select='id(x | y)'/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

This example doesn't generate significant output. It simply demonstrates that no errors are generated by the above XPath expressions.

See Also

Sample XML File for XPath Syntax (inventory.xml) | XPath Examples


Location Paths

A location path is an important kind of expression that selects a set of nodes relative to the context node. The result of evaluating the expression is the node-set containing the nodes selected by the location path. Location paths can recursively contain expressions that are used to filter sets of nodes.

This and the following topics include the syntax and pieces of location paths.

  • Location Steps
  • Axes
  • Node Tests
  • Predicates
  • Location Path Examples

Here are some examples of location paths.

To select the para element of the context node, you can use the following location path.

child::para

To select all element children of the context node, use the following.

child::*

And to select all text node children of the context node, use the following.

child::text()

Location paths are composed of one or more location steps, each separated by a "/". Each step in turn selects a set of nodes relative to the context node. The location steps are strung together from left to right. The left-most location step selects a set of nodes relative to the context node, which are then used as the context for the following step, and so on, until all steps have been processed.

For example, the following selects the para element children of the div element children of the context node.

child::div/child::para


Location Steps

A location step selects a set of nodes relative to the context node. It is composed of three parts.

Axis
Specifies the tree relationship between the nodes selected by the location step and the context node.
Node test
Specifies the node type and expanded-name of the nodes selected by the location step.
Zero or more predicates
Use expressions to further refine the set of nodes selected by the location step.

The syntax for a location step is the axis name and node test separated by a double colon, followed by zero or more expressions, each in square brackets.

For example, in the following, child is the name of the axis, para is the node test, and [position()=1] is a predicate.

child::para[position()=1]

The node-set selected by the location step is the node-set that results from generating an initial node-set from the axis and node test, and then filtering that node-set by each of the predicates in turn.

The initial node-set consists of the nodes having the relationship to the context node specified by the axis and having the node type and expanded-name specified by the node test. For example, a location step descendant::para selects the para element descendants of the context node: descendant specifies that each node in the initial node-set must be a descendant of the context; para specifies that each node in the initial node-set must be an element named "para". The available axes are described in Axes. The available node tests are described in Node Tests. The meaning of some node tests is dependent on the axis.

The initial node-set is filtered by the first predicate to generate a new node-set; this new node-set is then filtered using the second predicate, and so on. The final node-set is the node-set selected by the location step. The axis affects how the expression in each predicate is evaluated, so the semantics of a predicate is defined with respect to an axis.


Axes

An axis is used in a location path to specify the tree relationship between the nodes selected by the location step and the context node.

Axes | Description
ancestor | Contains the ancestors of the context node; the ancestors of the context node consist of the parent of the context node and the parent's parent and so on; thus the ancestor axis will always include the root node unless the context node is the root node.
ancestor-or-self | Contains the context node and the ancestors of the context node; thus the ancestor axis will always include the root node.
attribute | Contains the attributes of the context node; the axis will be empty unless the context node is an element.
child | Contains the children of the context node.
descendant | Contains the descendants of the context node; a descendant is a child or a child of a child and so on; thus the descendant axis never contains attribute or namespace nodes.
descendant-or-self | Contains the context node and the descendants of the context node.
following | Contains all nodes in the same document as the context node that are after the context node in document order, excluding any descendants and excluding attribute nodes and namespace nodes.
following-sibling | Contains all the following siblings of the context node; if the context node is an attribute node or namespace node, the following-sibling axis is empty.
namespace | Contains the namespace nodes of the context node; the axis will be empty unless the context node is an element.
parent | Contains the parent of the context node, if there is one.
preceding | Contains all nodes in the same document as the context node that are before the context node in document order, excluding any ancestors and excluding attribute nodes and namespace nodes.
preceding-sibling | Contains all the preceding siblings of the context node; if the context node is an attribute node or namespace node, the preceding-sibling axis is empty.
self | Contains just the context node itself.

Remarks

namespace

Each element has an associated set of namespace nodes, one for each distinct namespace prefix that is in scope for the element (including the xml prefix, which is implicitly declared by the XML Namespaces Recommendation) and one for the default namespace if one is in scope for the element. The element is the parent of each of these namespace nodes; however, a namespace node is not a child of its parent element. Elements never share namespace nodes: if one element node is not the same node as another element node, then none of the namespace nodes of the one element node will be the same node as the namespace nodes of another element node. This means that an element will have a namespace node:

  • for every attribute on the element whose name starts with xmlns:
  • for every attribute on an ancestor element whose name starts xmlns: unless the element itself or a nearer ancestor redeclares the prefix
  • for an xmlns attribute, if the element or some ancestor has an xmlns attribute, and the value of the xmlns attribute for the nearest such element is non-empty

The "sample" element in the following instance

<A xmlns="urn:A">
  <B xmlns:test="sample">
    <sample xmlns:sampletest="sampletest"/>
  </B>
</A>

contains the following namespace nodes

xmlns="urn:A"

xmlns:test="sample"

xmlns:sampletest="sampletest"

The "sample" element in the following instance

<A xmlns="urn:A">
  <B xmlns="" xmlns:test="sample">
    <sample xmlns:sampletest="sampletest" xmlns:bar="test"/>
  </B>
</A>

contains the following namespace nodes

xmlns:sampletest="sampletest"

xmlns:test="test"

Note An attribute xmlns="" "undeclares" the default namespace.

A namespace node has an expanded-name: the local part is the namespace prefix (this is empty if the namespace node is for the default namespace); the namespace Uniform Resource Identifier (URI) is always null.

The string-value of a namespace node is the namespace URI that is being bound to the namespace prefix; if it is relative, it must be resolved just like a namespace URI in an expanded-name.

Examples

following

Given the following instance document:

<A>
  <B>
    <C>sample</C>
    <C>sample2</C>
  </B>
  <B>
    <C>sample</C>
    <C>sample2</C>
    <D>sample3</D>
  </B>
</A>

The following query: "A/B[1]/following::*" returns the following nodes.

<B>
    <C>sample</C>
    <C>sample2</C>
    <D>sample3</D>
</B>
<C>sample</C>
<C>sample2</C>
<D>sample3</D>

The following query: "A/B[1]/following::node()" returns the following nodes.

<B>
    <C>sample</C>
    <C>sample2</C>
    <D>sample3</D>
</B>
<C>sample</C>
sample
<C>sample2</C>
sample2
<D>sample3</D>
sample3

preceding

Given the following instance document:

<A>
  <B>
    <C test="sampletest">sample</C>
    <C>sample2</C>
  </B>
  <B>
    <C>sample</C>
    <C>sample2</C>
    <D>sample3</D>
  </B>
</A>

The following query: "A/B[2]/preceding::*" returns the following nodes.

<B>
  <C test="sampletest">sample</C>
  <C>sample2</C>
</B>
<C>sample</C>
<C>sample2</C>

following-sibling

Given the following instance document:

<A>
  <B>
    <C test="sampletest">sample</C>
    <C>sample2</C>
  </B>
  <B>
    <C>sample</C>
    <C>sample2</C>
    <D>sample3</D>
  </B>
</A>

The following query: "A/B[1]/following-sibling::*" returns the following nodes.

<B>
  <C>sample</C>
  <C>sample2</C>
  <D>sample3</D>
</B>

preceding-sibling

Given the following instance document:

<A>
  <B>
    <C test="sampletest">sample</C>
    <C>sample2</C>
  </B>
  <B>
    <C>sample</C>
    <C>sample2</C>
    <D>sample3</D>
  </B>
</A>

The following query: "A/B[2]/preceding-sibling::*" returns the following nodes.

<B>
  <C test="sampletest">sample</C>
  <C>sample2</C>
</B>


Node Tests

A node test specifies the node type and expanded name of the nodes selected by the location step. Every axis has a principal node type. If an axis can contain elements, the principal node type is element; otherwise it is the type of the nodes that the axis can contain. Therefore,

  • for the attribute axis, the principal node type is attribute.
  • for the namespace axis, the principal node type is namespace.
  • for other axes, the principal node type is element.

A node test that is a QName is True if and only if the type of the node is the principal node type and has an expanded-name equal to the expanded-name specified by the QName. For example, child::para selects the para element children of the context node; if the context node has no para children, it will select an empty set of nodes.

A QName in the node test is expanded into an expanded-name using the namespace declarations from the expression context. This is the same way expansion is done for element type names in start and end tags except that the default namespace declared with xmlns is not used: if the QName does not have a prefix, the namespace URI is Null (this is the same way attribute names are expanded). It is an error if the QName has a prefix for which there is no namespace declaration in the expression context.

A node test * is True for any node of the principal node type. For example, child::* will select all element children of the context node, and attribute::* will select all attributes of the context node.

A node test can have the form NCName:*. In this case, the prefix is expanded in the same way as with a QName, using the context namespace declarations. It is an error if there is no namespace declaration for the prefix in the expression context. The node test will be True for any node of the principal type whose expanded-name has the namespace Uniform Resource Identifier (URI) to which the prefix expands, regardless of the local part of the name.

Available node tests are listed in the following table.

comment() | Returns True for a comment node.
node() | Returns True for a node of any type.
processing-instruction() | Returns True for a processing instruction node.
text() | Returns True for a text node.

The node test text() is true for any text node. For example, child::text() selects the text node children of the context node. In a similar way, the node test comment() is True for any comment node, and the node test processing-instruction() is True for any processing instruction. The processing-instruction() test may have an argument that is literal; in this case, it is True for any processing instruction that has a name equal to the value of the literal.

A node test node() is True for any node of any type.

See Also

Constructing the Node-Test Portion of a Location Step | Constructing the Node-Test Portion of an XPath Expression


Predicates

A predicate filters a node-set with respect to an axis to produce a new node-set. For each node in the node-set to be filtered, the expression is evaluated with that node as the context node, with the number of nodes in the node-set as the context size, and with the "proximity position" of the node in the node-set with respect to the axis as the context position; if the expression evaluates to True for that node, the node is included in the new node-set; otherwise it is not included.

An axis is either a forward axis or a reverse axis. An axis that only ever contains the context node or nodes that are after the context node in document order is a forward axis. An axis that only ever contains the context node or nodes that are before the context node in document order is a reverse axis. Thus ancestor and ancestor-or-self are reverse axes; all other axes are forward axes. Because the self axis always contains at most one node, it makes no difference whether it is a forward or reverse axis. The proximity position of a member of a node-set with respect to an axis is defined as the position of the node in the node-set ordered in document order if the axis is a forward axis and ordered in reverse document order if the axis is a reverse axis. The first position is 1.

A predicate expression is evaluated by evaluating the expression and converting the result to a Boolean. If the result is a number, it will be converted to True if the number is equal to the context position or converted to False otherwise; if the result is not a number, it will be converted to a Boolean. Thus a location path para[3] is equivalent to para[position()=3].


Location Path Examples

The following examples illustrate the use of location paths.

Select all the children of the context node, whatever their node type:

child::node()

Select the name attribute of the context node:

attribute::name

Select all the attributes of the context node:

attribute::*

Select the para element descendants of the context node:

descendant::para

Select all div ancestors of the context node:

ancestor::div

Select the div ancestors of the context node and, if the context node is a div element, the context node as well:

ancestor-or-self::div

Select the para element descendants of the context node and, if the context node is a para element, the context node as well:

descendant-or-self::para

Select the context node if it is a para element; otherwise select nothing:

self::para

Select the para element descendants of the chapter element children of the context node:

child::chapter/descendant::para

Select all para grandchildren of the context node:

child::*/child::para

Select the document root (which is always the parent of the document element):

/

Select all the para elements in the same document as the context node:

/descendant::para

Select all the item elements that have an olist parent and that are in the same document as the context node:

/descendant::olist/child::item

Select the first para child of the context node:

child::para[position()=1]

Select the last para child of the context node:

child::para[position()=last()]

Select the next-to-last para child of the context node:

child::para[position()=last()-1]

Select all the para children of the context node other than the first para child of the context node:

child::para[position()&gt;1]

Select the forty-second figure element in the document:

/descendant::figure[position()=42]

Select the second section of the fifth chapter of the doc document element:

/child::doc/child::chapter[position()=5]/child::section[position()=2]

Select all para children of the context node that have a type attribute with value "warning":

child::para[attribute::type="warning"]

Select the fifth para child of the context node that has a type attribute with value "warning":

child::para[attribute::type="warning"][position()=5]

Select the fifth para child of the context node if that child has a type attribute with value warning":

child::para[position()=5][attribute::type="warning"]

Select the chapter children of the context node that have one or more title children with string value equal to "Introduction":

child::chapter[child::title=Introduction"]

Select the chapter children of the context node that have one or more title children:

child::chapter[child::title]

Select the chapter and appendix children of the context node:

child::*[self::chapter or self::appendix]

Select the last chapter or appendix child of the context node:

child::*[self::chapter or self::appendix][position()=last()]

See Also

XPath Examples


XPath Examples

This topic reviews the examples that appear throughout the XSLT Reference. All are based on the Sample XML File for XPath Syntax (inventory.xml). For an example of using an XPath expression in a test file, see Example of Unions ( | ), at the bottom of this topic.

Find all author elements within the current context:

./author

Note that the above is equivalent to the following:

author

Find all first.name elements:

first.name

Find the document element (bookstore) of this document:

/bookstore

Find all author elements that are children of the current context node (for example, /bookstore/book):

//author

Find all bookstores where the value of the specialty attribute is equal to "textbooks":

/bookstore[@specialty = "textbooks"]

Find all books where the value of the style attribute on the book is equal to the value of the specialty attribute of the bookstore element at the root of the document:

book[/bookstore/@specialty = @style]

Find all first-name elements within an author element:

author/first-name

In the above example, note that the author children of the current context are found, and then first-name children are found relative to the context of the author elements.

Find all title elements one or more levels deep in the bookstore (arbitrary descendants):

bookstore//title

Note that the above is different from the following pattern, which finds all title elements that are grandchildren of bookstore elements:

bookstore/*/title

Find emph elements anywhere inside book excerpts, anywhere inside the bookstore:

bookstore//book/excerpt//emph

Find all titles one or more levels deep in the current context (note that this situation is essentially the only one in which the period notation is required):

.//title

Find all element children of author elements:

author/*

Find all last names that are grandchildren of books:

book/*/last-name

Find the grandchildren elements of the current context:

*/*

Find the book element from the "my" namespace:

my:book

Find all elements from the "my" namespace:

my:*

Find all elements with the specialty attribute:

*[@specialty]

Find the style attribute of the current element context:

@style

Find the exchange attribute on price elements within the current context:

price/@exchange

The following example does not return anything, because attributes do not contain element children. It is allowed by the XML Path Language (XPath) grammar, but is not strictly valid:

price/@exchange/total

Find all books with style attributes:

book[@style]

Find the style attribute for all book elements:

book/@style

Find all attributes of the current element context:

@*

Find all attributes from the "my" namespace (this does not include unqualified attributes on elements from the "my" namespace):

@my:*

Find all first-name elements (the following examples are equivalent):

./first-name
first-name

Find all unqualified book elements:

book

Find the first author element:

author[1]

Find the third author element that has a first-name:

author[first-name][3]

Note that indexes are relative to the parent. Consider the following data:

<x>
  <y/>
  <y/>
</x>
<x>
  <y/>
  <y/>
</x>

Find the first y from each x, for the above data:

x/y[1]
x/y[position() = 1]

Find the first y from the entire set of y elements within x elements:

(x/y)[1]

Find the second y from the first x:

x[1]/y[2]

Find the last book:

book[last()]

Find the last author for each book:

book/author[last()]

Find the last author from the entire set of authors of books:

(book/author)[last()]

Find all books that contain at least one excerpt element:

book[excerpt]

Find all titles of books that contain at least one excerpt element:

book[excerpt]/title

Find all authors of books where the book contains at least one excerpt and the author has at least one degree:

book[excerpt]/author[degree]

Find all books that have authors with at least one degree:

book[author/degree]

Find all books that have an excerpt and a title:

book[excerpt][title]

Find all author elements that contain at least one degree and one award:

author[degree and award]

Find all author elements that contain at least one degree or award and at least one publication:

author[(degree or award) and publication]

Find all author elements that contain at least one degree element and that contain no publication elements:

author[degree and not(publication)]

Find all author elements that contain publication elements but do not contain either degree elements or award elements:

author[not(degree or award) and publication]

Find all author elements that contain a last-name element with the value Bob:

author[last-name = "Bob"]

Find all author elements where the first last-name is Bob:

author[last-name[1] = "Bob"]
author[last-name = "Bob"]

Find all degrees where the from attribute is not equal to "Harvard":

degree[@from != "Harvard"]

Find all authors where the last name is the same as the /guest/last-name element:

author[last-name = /guest/last-name]

The above example assumes there is only one last-name; for more information, see Set Operations.

Find all authors whose text is "Matthew Bob":

author[. = "Matthew Bob"]

Find all author elements whose last name is "Bob" and whose price is > 50:

author[last-name = "Bob" and price &gt; 50]

Note that the above example assumes there is only one last-name and price for an author. For more information, see Set Operations.

Find all authors whose last name begins with "M" or greater:

author[last-name &gt; "M"]

Find all authors whose last name begins with "M" or greater, when an author can have several last names in the schema:

author[not(last-name &lt; "M")]

Note that in the above example, you cannot use author[all last-name &gt;= "M"], because all is not supported by XPath.

Find the first three books (1, 2, 3):

book[position() &lt;= 3]

Find all author elements where any one of the last names is Bob:

author[last-name = "Bob"]

Find all author elements where none of the last-name elements is Bob:

author[not(last-name = "Bob")]

Find all author elements containing a first-name child whose text is "Bob":

author[first-name = "Bob"]

Note that the above example and the following examples assume there is only one first-name child for an author.

Find all author elements containing any child element whose text is "Bob":

author[* = "Bob"]

Find author elements equal to "Joe Bob":

author[last-name = "Bob" and first-name = "Joe"]

Find the intl attribute equal to "Canada":

price[@intl = "Canada"]

Find the first 3 degrees:

degree[position() &lt; 3]

Find the second text node in each p element in the current context:

p/text()[2]

Find the nearest book ancestor of the current element:

ancestor::book[1]

Find the nearest ancestor book that has an author element:

ancestor::book[author][1]

Find the nearest ancestor author element that is contained in a book element:

ancestor::author[parent::book][1]

Example of Unions ( | )

This example demonstrates unions. The following XPath expression finds the green and blue nodes in the XML file:

x | y/x

XML File (data1.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="union.xsl"?>
<root>
   <x>green</x>
   <y>
      <x>blue</x>
      <x>blue</x>
   </y>
   <z>
      <x>red</x>
      <x>red</x>
   </z>
   <x>green</x>
</root>

XSLT File (union.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="root">
   <xsl:for-each select="x | y/x">
      <xsl:value-of select="."/>
   </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Formatted Output

greenbluebluegreen

Processor Output

<?xml version="1.0" encoding="UTF-16"?>greenbluebluegreen

See Also

Sample XML File for XPath Syntax (inventory.xml) | Location Path Examples


XPath Functions

XML Path Language (XPath) functions are used to evaluate expressions.

Each function in the function library is specified using a function prototype that provides the return type, function name, and argument type. If an argument type is followed by a question mark, the argument is optional; otherwise, the argument is required. Function names are case-sensitive.

The functions are divided into groups.

Node-Set | Takes a node-set argument, returns a node set, or returns/provides information about a particular node within a node set.
String | Performs evaluations, formatting, and manipulation on string arguments.
Boolean | Evaluates the argument expressions to obtain a Boolean result.
Number | Evaluates the argument expressions to obtain a numeric result.
Microsoft Extension Functions | Microsoft extension functions to XPath that provide the ability to select nodes by XSD type. Also includes string comparison, number comparison, and date/time conversion functions.

Examples

Find all text children of author elements:

author/text()

Find all elements that have text node or CDATA node children:

*[text()]

Find the last author for each book:

book/author[last()]


Node-Set Functions

Node-Set functions take a node-set argument, return a node set, or return/provide information about a particular node within a node set.

Node-Set Functions

count | Returns the number of nodes in the node-set argument.
id | Selects elements by their unique ID.
last | Returns a number equal to context size of the expression evaluation context.
local-name | Returns the local part of the expanded name of the node in the node-set argument that is first in document order.
name | Returns a string containing a QName representing the expanded name of the node in the node-set argument that is first in document order.
namespace-uri | Returns the namespace Uniform Resource Identifier (URI) of the expanded name of the node in the node-set argument that is first in document order.
position | Returns the index number of the node within the parent.

See Also

Processing Node-Sets by Using Node-Set Functions | Qualified Names


count Function

Returns the number of nodes in the node-set argument.

number count(node-set)

Examples

Short examples of the count() function are shown in the following topics.

xsl:strip-space Element

Determining the Context Size

Design Patterns for Using Parameters

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD) | Processing Node-Sets by Using Node-Set Functions


id Function

Selects elements by their unique ID.

node-set id(object)

Remarks

When the argument is of type node-set, the result is the union of the result of applying id() to the string value of each of the nodes in the node-set argument.

When the argument is of any other type, it is converted to a string and then split into a white space–separated list of tokens (white space is any sequence of characters matching the production); the result is a node-set containing the elements in the same document as the context node that have a unique ID equal to any of the tokens in the list.

The following selects the element with the unique ID "mysample":

id("mysample")

The following selects the fifth para child of the element with unique ID "mysample":

id("mysample")/child::para[position()=5]

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


last Function

Returns a number equal to context size of the expression evaluation context.

number last()

Remarks

The following finds the last author for each book:

book/author[last()]

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


local-name Function

Returns the local part of the expanded name of the node in the node-set argument that is first in document order.

string local-name(node-set?)

Remarks

If the node-set argument is empty or the first node has no expanded name, an empty string is returned. If the argument is omitted, it defaults to a node-set with the context node as its only member.

Sample

XML File (data.xml)

<?xml-stylesheet type="text/xsl" href="sample.xsl"?>
<b:catalog xmlns:b="x-schema:book-schema.xml">
   <b:book id="bk101">
      <b:author>Gambardella, Matthew</b:author>
      <b:title>XML Developer's Guide</b:title>
      <b:genre>Computer</b:genre>
      <b:price>44.95</b:price>
      <b:publish_date>2000-10-01</b:publish_date>
      <b:description>An in-depth look at creating applications with XML.</b:description>
   </b:book>
   <b:book id="bk102">
      <b:author>Ralls, Kim</b:author>
      <b:title>Midnight Rain</b:title>
      <b:genre>Fantasy</b:genre>
      <b:price>5.95</b:price>
      <b:publish_date>2000-12-16</b:publish_date>
      <b:description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</b:description>
   </b:book>
</b:catalog>

XSLT File (sample.xsl)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
  <xsl:template match="/">
      <html>
         <body>
            <h3>local-name() Function</h3>

            <xsl:apply-templates />

         </body>
      </html>
  </xsl:template>

  <xsl:template match="*">
      <xsl:value-of select="local-name()"/> = <xsl:value-of select="text()"/><br/>
      <xsl:apply-templates select="*"/>
  </xsl:template>
</xsl:stylesheet>

Auxiliary XSLT File (book-schema.xml)

<Schema name="books" xmlns="urn:schemas-microsoft-com:xml-data"
           xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <ElementType name="author"/>
   <ElementType name="title"/>
   <ElementType name="genre"/>
   <ElementType name="price"/>
   <ElementType name="publish_date"/>
   <ElementType name="description"/>
   <AttributeType name="id" dt:type="id"/>

   <ElementType name="catalog">
      <element type="book"/>
   </ElementType>

   <ElementType name="book" model="closed" content="eltOnly">
      <attribute type="id"/>
      <element type="author"/>
      <element type="title"/>
      <element type="genre"/>
      <element type="price"/>
      <element type="publish_date"/>
      <element type="description"/>
   </ElementType>
</Schema>

Formatted Output

local-name() Function

catalog =

book =

author = Gambardella, Matthew

title = XML Developer's Guide

genre = Computer

price = 44.95

publish_date = 2000-10-01

description = An in-depth look at creating applications with XML.

book =

author = Ralls, Kim

title = Midnight Rain

genre = Fantasy

price = 5.95

publish_date = 2000-12-16

description = A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.

Processor Output

<html>
<body>
<h3>local-name() Function</h3>catalog = <br>book = <br>author = Gambardella, Matthew<br>title = XML Developer's Guide<br>genre = Computer<br>price = 44.95<br>publish_date = 2000-10-01<br>description = An in-depth look at creating applications with XML.<br>book = <br>author = Ralls, Kim<br>title = Midnight Rain<br>genre = Fantasy<br>price = 5.95<br>publish_date = 2000-12-16<br>description = A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.<br></body>
</html>

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


name Function

Returns a string containing a QName representing the expanded name of the node in the node-set argument that is first in document order.

string name(node-set?)

Remarks

The QName must represent the expanded name with respect to the namespace in effect on the node. This need not be the case if there are namespace declarations in effect on the node that associate multiple prefixes with the same namespace. If the node-set argument is empty or the first node has no expanded name, an empty string is returned. If the argument it omitted, it defaults to a node-set with the context node as its only member.

Example

XML File (bcat.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="sample.xsl"?>
<b:catalog xmlns:b="x-schema:book-schema.xml">
   <b:book id="bk101">
      <b:author>Gambardella, Matthew</b:author>
      <b:title>XML Developer's Guide</b:title>
      <b:genre>Computer</b:genre>
      <b:price>44.95</b:price>
      <b:publish_date>2000-10-01</b:publish_date>
      <b:description>An in-depth look at creating applications with XML.</b:description>
   </b:book>
   <b:book id="bk102">
      <b:author>Ralls, Kim</b:author>
      <b:title>Midnight Rain</b:title>
      <b:genre>Fantasy</b:genre>
      <b:price>5.95</b:price>
      <b:publish_date>2000-12-16</b:publish_date>
      <b:description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</b:description>
   </b:book>
</b:catalog>

XSLT File (sample.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template match="/">
    <html>
       <body>
          <h3>name() Function</h3>

          <xsl:apply-templates />

       </body>
    </html>
</xsl:template>

<xsl:template match="*">
    <xsl:value-of select="name()"/> = <xsl:value-of select="text()"/><br/>
    <xsl:apply-templates select="*"/>
</xsl:template>

</xsl:stylesheet>

Auxiliary XSLT File (book-schema.xml)

<Schema name="books" xmlns="urn:schemas-microsoft-com:xml-data"
           xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <ElementType name="author"/>
   <ElementType name="title"/>
   <ElementType name="genre"/>
   <ElementType name="price"/>
   <ElementType name="publish_date"/>
   <ElementType name="description"/>
   <AttributeType name="id" dt:type="id"/>

   <ElementType name="catalog">
      <element type="book"/>
   </ElementType>

   <ElementType name="book" model="closed" content="eltOnly">
      <attribute type="id"/>
      <element type="author"/>
      <element type="title"/>
      <element type="genre"/>
      <element type="price"/>
      <element type="publish_date"/>
      <element type="description"/>
   </ElementType>
</Schema>

Formatted Output

name() Function

b:catalog =

b:book =

b:author = Gambardella, Matthew

b:title = XML Developer's Guide

b:genre = Computer

b:price = 44.95

b:publish_date = 2000-10-01

b:description = An in-depth look at creating applications with XML.

b:book =

b:author = Ralls, Kim

b:title = Midnight Rain

b:genre = Fantasy

b:price = 5.95

b:publish_date = 2000-12-16

b:description = A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.

Processor Output

<html>
<body>
<h3>name() Function</h3>b:catalog = <br>b:book = <br>b:author = Gambardella, Matthew<br>b:title = XML Developer's Guide<br>b:genre = Computer<br>b:price = 44.95<br>b:publish_date = 2000-10-01<br>b:description = An in-depth look at creating applications with XML.<br>b:book = <br>b:author = Ralls, Kim<br>b:title = Midnight Rain<br>b:genre = Fantasy<br>b:price = 5.95<br>b:publish_date = 2000-12-16<br>b:description = A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.<br></body>
</html>

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


namespace-uri Function

Returns the namespace Uniform Resource Identifier (URI) of the expanded name of the node in the node-set argument that is first in document order.

string namespace-uri(node-set?)

Remarks

If the node-set argument is empty, the first node has no expanded name or the namespace URI of the expanded name is Null and an empty string is returned. If the argument is omitted, it defaults to a node-set with the context node as its only member.

Note The string returned will be empty except for element nodes and attribute nodes.

Sample

XML File (data.xml)

<?xml-stylesheet type="text/xsl" href="sample.xsl"?>
<b:catalog xmlns:b="x-schema:book-schema.xml">
   <b:book id="bk101">
      <b:author>Gambardella, Matthew</b:author>
      <b:title>XML Developer's Guide</b:title>
      <b:genre>Computer</b:genre>
      <b:price>44.95</b:price>
      <b:publish_date>2000-10-01</b:publish_date>
      <b:description>An in-depth look at creating applications with XML.</b:description>
   </b:book>
   <b:book id="bk102">
      <b:author>Ralls, Kim</b:author>
      <b:title>Midnight Rain</b:title>
      <b:genre>Fantasy</b:genre>
      <b:price>5.95</b:price>
      <b:publish_date>2000-12-16</b:publish_date>
      <b:description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</b:description>
   </b:book>
</b:catalog>

XSLT File (sample.xsl)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html"/>
  <xsl:template match="/">
      <html>
         <body>
            <h3>namespace-uri() Function</h3>

            <table width="100%" border="1">
               <tr>
                  <td width="25%"><b>namespace-uri()</b></td>
                  <td width="25%"><b>name()</b></td>
                  <td width="25%"><b>local-name</b></td>
                  <td width="25%"><b>text()</b></td>
               </tr>
               <xsl:apply-templates />
            </table>
         </body>
      </html>
  </xsl:template>

  <xsl:template match="*">
      <tr>
         <td>
            <xsl:value-of select="namespace-uri()"/>
         </td>
         <td>
            <xsl:value-of select="name()"/>
         </td>
         <td>
            <xsl:value-of select="local-name()"/>
         </td>
         <td>
            <xsl:value-of select="text()"/>
         </td>
      </tr>
      <xsl:apply-templates select="*"/>
  </xsl:template>
</xsl:stylesheet>

Auxiliary XSLT File (book-schema.xml)

<Schema name="books" xmlns="urn:schemas-microsoft-com:xml-data"
           xmlns:dt="urn:schemas-microsoft-com:datatypes">
   <ElementType name="author"/>
   <ElementType name="title"/>
   <ElementType name="genre"/>
   <ElementType name="price"/>
   <ElementType name="publish_date"/>
   <ElementType name="description"/>
   <AttributeType name="id" dt:type="id"/>

   <ElementType name="catalog">
      <element type="book"/>
   </ElementType>

   <ElementType name="book" model="closed" content="eltOnly">
      <attribute type="id"/>
      <element type="author"/>
      <element type="title"/>
      <element type="genre"/>
      <element type="price"/>
      <element type="publish_date"/>
      <element type="description"/>
   </ElementType>
</Schema>

Formatted Output

Processor Output

<html>
<body>
<h3>namespace-uri() Function</h3>
<table width="100%" border="1">
<tr>
<td width="25%"><b>namespace-uri()</b></td>
<td width="25%"><b>name()</b></td>
<td width="25%"><b>local-name</b></td>
<td width="25%"><b>text()</b></td>
</tr>
<tr>
<td>x-schema:book-schema.xml</td>
<td>b:catalog</td>
<td>catalog</td>
<td></td>
</tr>
...
<tr>
<td>x-schema:book-schema.xml</td>
<td>b:author</td>
<td>author</td>
<td>Gambardella, Matthew</td>
</tr>
...
</table>
</body>
</html>

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


position Function

Returns the index number of the node within the parent.

number position()

Remarks

The first node returns a position of 1.

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


String Functions

String functions perform evaluations, format and manipulate string arguments, or convert an object to a string.

String Functions

concat | Returns the concatenation of the arguments.
contains | Returns true if the first argument string contains the second argument string; otherwise returns false.
normalize-space | Returns the argument string with the white space stripped.
starts-with | Returns true if the first argument string starts with the second argument string; otherwise returns false.
string | Converts an object to a string.
string-length | Returns the number of characters in the string.
substring | Returns the substring of the first argument starting at the position specified in the second argument and the length specified in the third argument.
substring-after | Returns the substring of the first argument string that follows the first occurrence of the second argument string in the first argument string.
substring-before | Returns the substring of the first argument string that precedes the first occurrence of the second argument string in the first argument string.
translate | Returns the first argument string with occurrences of characters in the second argument string replaced by the character at the corresponding position in the third argument string.


concat Function

Returns the concatenation of the arguments.

string concat(string, string, string*)

Remarks

If an argument is not of type string, it is first converted to a string and then evaluated.

Example

The following function call returns "abcdefg".

concat("abc", "d", "ef", "g")

The following function call returns "abc3efg".

concat("abc", 3, "ef", "g")

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


contains Function

Returns true if the first argument string contains the second argument string; otherwise returns false.

boolean contains(string, string)

Remarks

If an argument is not of type string, it is first converted to a string and then evaluated.

The following function call returns false.

contains("mysampletest", "oba")

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


normalize-space Function

Returns the argument string with the white space stripped.

string normalize-space(string)

Remarks

White space is normalized by stripping leading and trailing white space and replacing sequences of white space characters with a single space. If the argument is omitted, the string-value of the context node is normalized and returned.

The following function call returns "abc":

normalize-space("  abc  ")

If an argument is not of type string, it is first converted to a string and then evaluated.

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


starts-with Function

Returns true if the first argument string starts with the second argument string; otherwise returns false.

boolean starts-with(string, string)

Remarks

If an argument is not of type string, it is first converted to a string and then evaluated.

The following function call returns true:

starts-with("mysampletest", "mysample")

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


string Function

Converts an object to a string.

string string(object?)

Remarks

An object is converted to a string as follows.

A node-set is converted to a string by returning the string value of the node in the node-set that is first in document order. If the node-set is empty, an empty string is returned.

A number is converted to a string as follows.

  • NaN is converted to the string NaN.
  • positive zero is converted to the string "0".
  • negative zero is converted to the string "0".
  • positive infinity is converted to the string "Infinity".
  • negative infinity is converted to the string "-Infinity".
  • If the number is an integer, the number is represented in decimal form as a number with no decimal point and no leading zeros, preceded by a minus sign (-) if the number is negative.
  • Otherwise, the number is represented in decimal form as a number with a decimal point and at least one digit before the decimal point and at least one digit after the decimal point, preceded by a minus sign (-) if the number is negative; there must be no leading zeros before the decimal point, apart possibly from the one required digit immediately before the decimal point; beyond the one required digit after the decimal point there must be as many, but only as many, more digits as are needed to uniquely distinguish the number from all other IEEE 754 numeric values.

The Boolean false value is converted to the string "false". The Boolean true value is converted to the string "true".

An object of a type other than the four basic types is converted to a string in a way that is dependent on that type.

If the argument is omitted, it defaults to a node-set with the context node as its only member.

Note The string function is not intended for converting numbers into strings for presentation to users. The format-number function and <xsl:number> element in XSL Transformations (XSLT) provide this functionality.

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD) | NaN Values | format-number Function


string-length Function

Returns the number of characters in the string.

number string-length(string)

Remarks

If the argument is omitted, it returns the number of characters in the string-value of the context node.

The following function call returns 4:

string-length("abcd")

If an argument is not of type string, it is first converted to a string and then evaluated.

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


substring Function

Returns the substring of the first argument starting at the position specified in the second argument and the length specified in the third argument.

string substring(string, number, number?)

Remarks

Each character in the string is considered to have a numeric position: the position of the first character is 1, the position of the second character is 2, and so on.

If the third argument is not specified, it returns the substring starting at the position specified in the second argument and continuing to the end of the string.

The following function call returns "234":

substring("12345",2,3)

The following function call returns "2345":

substring("12345",2)

The returned substring contains those characters for which the position of the character is greater than or equal to the rounded value of the second argument, and if the third argument is specified, less than the sum of the rounded value of the second argument and the rounded value of the third argument. The comparisons and addition used for the preceding follow the standard IEEE 754 rules; rounding is done as if by a call to the round function.

The following examples illustrate unusual cases.

substring("12345", 1.5, 2.6) returns "234"
substring("12345", 0, 3) returns "12"
substring("12345", 0 div 0, 3) returns ""
substring("12345", 1, 0 div 0) returns ""
substring("12345", -42, 1 div 0) returns "12345"
substring("12345", -1 div 0, 1 div 0) returns ""

Example

This example demonstrates the preceding substring() expressions.

XML File

None; the XSLT file calls itself.

XSLT File (substring.xsl)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="substring.xsl"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   substring("12345",2,3) =
      <xsl:value-of select='substring("12345",2,3)'/><br/>
   substring("12345",2) =
      <xsl:value-of select='substring("12345",2)'/><br/>
   substring("12345", 1.5, 2.6) =
      <xsl:value-of select='substring("12345", 1.5, 2.6)'/><br/>
   substring("12345", 0, 3) =
      <xsl:value-of select='substring("12345", 0, 3)'/><br/>
   substring("12345", 0 div 0, 3) =
      <xsl:value-of select='substring("12345", 0 div 0, 3)'/><br/>
   substring("12345", 1, 0 div 0) =
      <xsl:value-of select='substring("12345", 1, 0 div 0)'/><br/>
   substring("12345", -42, 1 div 0) =
      <xsl:value-of select='substring("12345", -42, 1 div 0)'/><br/>
   substring("12345", -1 div 0, 1 div 0) =
      <xsl:value-of select='substring("12345", -1 div 0, 1 div 0)'/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

substring("12345",2,3) = 234
substring("12345",2) = 2345
substring("12345", 1.5, 2.6) = 234
substring("12345", 0, 3) = 12
substring("12345", 0 div 0, 3) =
substring("12345", 1, 0 div 0) =
substring("12345", -42, 1 div 0) = 12345
substring("12345", -1 div 0, 1 div 0) =

Processor Output

<?xml version="1.0" encoding="UTF-16"?>
   substring("12345",2,3) =
      234<br />
   substring("12345",2) =
      2345<br />
   substring("12345", 1.5, 2.6) =
      234<br />
   substring("12345", 0, 3) =
      12<br />
   substring("12345", 0 div 0, 3) =
      <br />
   substring("12345", 1, 0 div 0) =
      <br />
   substring("12345", -42, 1 div 0) =
      12345<br />
   substring("12345", -1 div 0, 1 div 0) =

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


substring-after Function

Returns the substring of the first argument string that follows the first occurrence of the second argument string in the first argument string, or the empty string if the first argument string does not contain the second argument string.

string substring-after(string, string)

Remarks

If an argument is not of type string, it is first converted to a string and then evaluated.

The following function call returns "04/01":

substring-after("1999/04/01","/")

The following function call returns "99/04/01":

substring-after("1999/04/01","19")

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


substring-before Function

Returns the substring of the first argument string that precedes the first occurrence of the second argument string in the first argument string, or the empty string if the first argument string does not contain the second argument string.

string substring-before(string, string)

Remarks

If an argument is not of type string, it is first converted to a string and then evaluated.

The following function call returns "1999":

substring-before("1999/04/01","/")

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


translate Function

Returns the first argument string with occurrences of characters in the second argument string replaced by the character at the corresponding position in the third argument string.

string translate(string, string, string)

Remarks

The following function call returns "BAr":

translate("bar","abc","ABC")

If there is a character in the second argument string with no character at a corresponding position in the third argument string (because the second argument string is longer than the third argument string), occurrences of that character in the first argument string are removed.

The following function call returns "AAA":

translate("--aaa--","abc-","ABC")

If a character occurs more than once in the second argument string, the first occurrence determines the replacement character. If the third argument string is longer than the second argument string, excess characters are ignored.

If an argument is not of type string, it is first converted to a string and then evaluated.

Example

This example demonstrates the preceding translate() expressions.

XML File

None; the XSLT file calls itself.

XSLT File (translate.xsl)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="translate.xsl"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   translate("bar","abc","ABC") =
      <xsl:value-of select='translate("bar","abc","ABC")'/>
   <br/>translate("--aaa--","abc-","ABC") =
      <xsl:value-of select='translate("--aaa--","abc-","ABC")'/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

translate("bar","abc","ABC") = BAr
translate("--aaa--","abc-","ABC") = AAA

Processor Output

<?xml version="1.0" encoding="UTF-16"?>
   translate("bar","abc","ABC") =
      BAr<br />translate("--aaa--","abc-","ABC") =
      AAA

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


Boolean Functions

The XML Path Language (XPath) syntax supports Boolean functions that return strings or numbers, and can be used with comparison operators in filter patterns.

Boolean Functions

boolean | Converts the argument to a Boolean.
false | Returns false.
lang | Returns true if the xml:lang attribute of the context node is the same as the argument string.
not | Returns true if the argument is false, otherwise, false.
true | Returns true.


boolean Function

Converts the argument to a Boolean.

boolean boolean(object)

Remarks

Converts its argument to a Boolean as follows.

  • A number is true if and only if it is neither positive or negative zero or NaN.
  • A node-set is true if and only if it is nonempty.
  • A string is true if and only if its length is nonzero.
  • An object of a type other than the four basic types is converted to a Boolean in a way that is dependent on that type. For more information about the basic types of objects, see Using XPath Expressions to Select Nodes.

Example

XML File

None; the XSLT file calls itself.

If you use the sample XML file, books.xml, and change the href attribute to reference bool.xsl, boolean(//book) resolves as true.

XSLT File (bool.xsl)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="bool.xsl"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template match="/">
    <html>
       <body>
          <h3>boolean() Function</h3>

          <ul>
             <li><b>boolean(0)</b> =
                <xsl:value-of select="boolean(0)"/>
             </li>
             <li><b>boolean(1)</b> =
                <xsl:value-of select="boolean(1)"/>
             </li>
             <li><b>boolean(-100)</b> =
                <xsl:value-of select="boolean(-100)"/>
             </li>
             <li><b>boolean(100)</b> =
                <xsl:value-of select="boolean(100)"/>
             </li>
             <li><b>boolean(NaN)</b> =
                <xsl:value-of select="boolean(NaN)"/>
             </li>
             <li><b>boolean('hello')</b> =
                <xsl:value-of select="boolean('hello')"/>
             </li>
             <li><b>boolean('')</b> =
                <xsl:value-of select="boolean('')"/>
             </li>
             <li><b>boolean(//book)</b> =
                <xsl:value-of select="boolean(//book)"/>
             </li>
             <li><b>boolean(//notfound)</b> =
                <xsl:value-of select="boolean(//notfound)"/>
             </li>
          </ul>
       </body>
    </html>
</xsl:template>

</xsl:stylesheet>

Formatted Output

boolean() Function

  • boolean(0) = false
  • boolean(1) = true
  • boolean(-100) = true
  • boolean(100) = true
  • boolean(NaN) = false
  • boolean('hello') = true
  • boolean('') = false
  • boolean(//book) = false
  • boolean(//notfound) = false

Processor Output

<html>
<body>
<h3>boolean() Function</h3>
<ul>
<li><b>boolean(0)</b> =
      false</li>
<li><b>boolean(1)</b> =
      true</li>
<li><b>boolean(-100)</b> =
      true</li>
<li><b>boolean(100)</b> =
      true</li>
<li><b>boolean(NaN)</b> =
      false</li>
<li><b>boolean('hello')</b> =
      true</li>
<li><b>boolean('')</b> =
      false</li>
<li><b>boolean(//book)</b> =
      true</li>
<li><b>boolean(//notfound)</b> =
      false</li>
</ul>
</body>
</html>

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD) | NaN Values | Sample XML File (books.xml)


false Function

Returns false.

boolean false()

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


lang Function

Returns true if the xml:lang attribute of the context node is the same as a sublanguage of the language specified by the argument string.

Syntax

boolean lang(string)

Remarks

The language of the context node is determined by the value of the xml:lang attribute on the context node, or if the context node has no xml:lang attribute, by the value of the xml:lang attribute on the nearest ancestor of the context node that has an xml:lang attribute. If there is no such attribute, lang() returns false. If there is such an attribute, lang() returns true if the attribute value is equal to the argument (ignoring case) or if there is a suffix starting with "-", such that the attribute value is equal to the argument, ignoring the suffix of the attribute value and ignoring case.

Given the following XML elements:

<para xml:lang="en"/>
<div xml:lang="en"><para/></div>
<para xml:lang="EN"/>
<para xml:lang="en-us"/>

The following function call returns true for all:

lang("en")

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


not Function

Returns true if the argument is false; otherwise false.

boolean not(boolean)

Example

In this example, the notexample.xsl stylesheet is applied to the books.xml document. For each book node, the value of the price element is evaluated. If it's not greater than 10, the value of the title element and the value of the price element are output to the browser.

XML File (books.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="notexample.xsl"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications with
 XML.</description>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies,
 an evil sorceress, and her own childhood to become queen of the world.</description>
   </book>
</catalog>

XSLT File (notexample.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <xsl:for-each select="//book[not(price &gt; 10)]">
      <xsl:value-of select="title"/> -
      $<xsl:value-of select="price"/><br/>
   </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Midnight Rain - $5.95

Processor Output

<?xml version="1.0" encoding="UTF-16"?>Midnight Rain -
      $5.95<br />

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


true Function

Returns true.

boolean true()

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


Number Functions

The XML Path Language (XPath) syntax supports Number functions that return strings or numbers and can be used with comparison operators in filter patterns.

Number Functions

ceiling | Returns the smallest integer that is not less than the argument.
floor | Returns the largest integer that is not greater than the argument.
number | Converts the argument to a number.
round | Returns an integer closest in value to the argument.
sum | Returns the sum of all nodes in the node-set. Each node is first converted to a number value before summing.


ceiling Function

Returns the smallest integer that is not less than the argument.

number ceiling(number)

Example

This example demonstrates ceiling() expressions.

XML File

None; the XSLT file calls itself.

XSLT File (ceiling.xsl)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="ceiling.xsl"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <p/>ceiling(2.5) =
      <xsl:value-of select='ceiling(2.5)'/>
   <p/>ceiling(-2.3) =
      <xsl:value-of select='ceiling(-2.3)'/>
   <p/>ceiling(4) =
      <xsl:value-of select='ceiling(4)'/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

ceiling(2.5) = 3

ceiling(-2.3) = -2

ceiling(4) = 4

Processor Output

<?xml version="1.0" encoding="UTF-16"?><p />ceiling(2.5) =
      3<p />ceiling(-2.3) =
      -2<p />ceiling(4) =
      4

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


floor Function

Returns the largest integer that is not greater than the argument.

number floor(number)

Example

This example demonstrates floor() expressions.

XML File

None; the XSLT file calls itself.

XSLT File (floor.xsl)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="floor.xsl"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <p/>floor(3.5) =
      <xsl:value-of select='floor(3.5)'/>
   <p/>floor(-1.3) =
      <xsl:value-of select='floor(-1.3)'/>
   <p/>floor(4) =
      <xsl:value-of select='floor(4)'/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

floor(3.5) = 3

floor(-1.3) = -2

floor(4) = 4

Processor Output

<?xml version="1.0" encoding="UTF-16"?><p />floor(3.5) =
      3<p />floor(-1.3) =
      -2<p />floor(4) =
      4

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


number Function

Converts the argument to a number.

number number(object?)

Remarks

Converts its argument to a number as follows.

  • A string that consists of optional white space followed by an optional minus sign followed by a number followed by white space is converted to the IEEE 754 number that is nearest (according to the IEEE 754 round-to-nearest rule) to the mathematical value represented by the string; any other string is converted to NaN.
  • Boolean true is converted to 1; Boolean false is converted to 0.
  • A node-set is first converted to a string and then converted in the same way as a string argument.
  • An object of a type other than the four basic types (node-set, Boolean, number, or string) is converted to a number in a way that is dependent on that type.

If the argument is omitted, it defaults to a node-set with the context node as its only member.

Note The number function should not be used for conversion of numeric data occurring in an element in an XML document unless the element is of a type that represents numeric data in a language-neutral format (that would typically be transformed into a language-specific format for presentation to a user). In addition, the number function cannot be used unless the language-neutral format used by the element is consistent with the XML Path Language (XPath) syntax for a number.

Example

XML File

None; the XSLT file calls itself.

XSLT File (number.xsl)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="number.xsl"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template match="/">
<html>
<body>
<h3>number() Function</h3>
<ul>
<li>
<b>number('2048')</b>
=
<xsl:value-of select="number('2048')"/>
</li>
<li>
<b>number('-2048')</b>
=
<xsl:value-of select="number('-2048')"/>
</li>
<li>
<b>number('text')</b>
=
<xsl:value-of select="number('text')"/>
</li>
<li>
<b>number('109.54')</b>
=
<xsl:value-of select="number('109.54')"/>
</li>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Formatted Output

number() Function

  • number('2048') = 2048
  • number('-2048') = -2048
  • number('text') = NaN
  • number('109.54') = 109.54

Processor Output

<html><body><h3>number() Function</h3><ul><li><b>number('2048')</b> =       2048</li><li><b>number('-2048')</b> =       2048</li><li><b>number('text')</b> =       NaN</li><li><b>number('109.54')</b> =       109.54</li></ul></body></html>

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


round Function

Returns an integer closest in value to the argument.

number round(number)

Remarks

If there are two such numbers, the one that is closest to positive infinity is returned.

If the argument is NaN, NaN is returned.

If the argument is positive infinity, positive infinity is returned.

If the argument is negative infinity, negative infinity is returned.

If the argument is positive zero, positive zero is returned.

If the argument is negative zero, negative zero is returned.

If the argument is less than zero but greater than or equal to -0.5, negative zero is returned.

For the last two cases, the result of calling the round() function is not the same as the result of adding 0.5 and then calling the floor() function because positive zero will be returned in such cases.

Example

This example demonstrates round() expressions.

XML File

None; the XSLT file calls itself.

XSLT File (round.xsl)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="round.xsl"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   round(2.6) =
      <xsl:value-of select='round(2.6)'/>
   <br/>round (2.4) =
      <xsl:value-of select='round (2.4)'/>
   <br/>round(2.5) =
      <xsl:value-of select='round(2.5)'/>
   <br/>round(-1.6) =
      <xsl:value-of select='round(-1.6)'/>
   <br/>round(-1.5) =
      <xsl:value-of select='round(-1.5)'/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

round(2.6) = 3
round (2.4) = 2
round(2.5) = 3
round(-1.6) = -2
round(-1.5) = -1

Processor Output

<?xml version="1.0" encoding="UTF-16"?>
   round(2.6) =
      3<br />round (2.4) =
      2<br />round(2.5) =
      3<br />round(-1.6) =
      -2<br />round(-1.5) =
      -1

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


sum Function

Returns the sum of all nodes in the node-set. Each node is first converted to a number value before summing.

number sum(node-set)

Example

This example demonstrates the XPath expression sum(//a). It returns 6, which is the sum of the numbers in <a> elements.

XML File (as.xml)

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="sum.xsl"?>
<root>
  <a>1</a>
  <a>3</a>
  <a>2</a>
</root>

XSLT File (sum.xsl)

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <xsl:value-of select='sum(//a)'/>
</xsl:template>

</xsl:stylesheet>

Formatted Output

6

Processor Output

<?xml version="1.0" encoding="UTF-16"?>6

See Also

Data Types in Schemas | XDR Data Types Reference | XML Data Types Reference (XSD)


Microsoft XPath Extension Functions

The XML Path Language (XPath) 1.0 does not support expressions that evaluate nodes based on data type, so MSXML provides a number of XPath extension functions for this purpose. XPath extension functions require a namespace prefix. For more information, see Defining Namespace Prefixes for Extension Functions.

XSD Support Extension Functions

Function | Description
ms:type-is | Compares the current node's data type against the specified node type.
ms:type-local-name ([node-set]) | Returns the nonqualified name of the XSD type of the current node or the first node (in document order) in the provided node-set.
ms:type-namespace-uri ([node-set]) | Returns the namespace URI associated with the XSD type of a current node or the first node (in document order) in the provided node-set.
ms:schema-info-available | Returns true if XSD information is available for a current node.

Miscellaneous Extension Functions

ms:string-compare | Performs lexicographical string comparison.
ms:utc | Converts the prefixed date/time related values into Coordinated Universal Time and into a fixed (normalized) representation that can be sorted and compared lexicographically.
ms:namespace-uri | Resolves the prefix part of a qualified name into a namespace URI.
ms:local-name | Returns the local name part of a qualified name by stripping out the namespace prefix.
ms:number | Takes a string argument in XSD format and converts it into an XPath number.
ms:format-date | Converts standard XSD date formats to characters suitable for output.
ms:format-time | Converts standard XSD time formats to characters suitable for output.


Defining Namespace Prefixes for Extension Funtions

Microsoft XML 4.0 Technology Preview - XSLT Reference

Defining Namespace Prefixes for Extension Functions

To use the Microsoft XPath Extension functions, you must use a qualified name. With namespace declarations, the prefix name (such as "ms:", "msxsl:", or "abc:") is user-defined. The value of the xmlns attribute, however, is fixed and must be "urn:schemas-microsoft-com:xslt". The following examples show how to use namespaces prefixes with extension functions.

For XSLT stylesheets, the declaration for the namespace prefix can appear in the style sheet's root <xml:stylesheet> element, as follows:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                          "xmlns:ms="urn:schemas-microsoft-com:xslt"
                          version="1.0">

If the namespace prefix is declared in the stylesheet's root, only the prefix is required with the function statement, as follows:

<xsl:for-each select="//[ms:type-local-name()='ID']"

The namespace prefix can also be defined within the XSLT element, as follows.

<xsl:for-each select="//[ms:type-local-name()='ID'] xmlns:ms="urn:schemas-microsoft-com:xslt">

When using the DOM, the namespace prefix is declared using the setProperty method of IXMLDOMDocument2.

docObj.setProperty("SelectionNamespaces", "xmlns:ms='urn:schemas-microsoft-com:xslt'")

See Also

setProperty method | Using Namespaces in Documents


Using XSD Extension Functions

The MSXML 4.0 Technology Preview provides a variety of extension functions that enable you to select nodes based on their XSD data type. It also provides handy functions that such as ms:string-compare that enables you to perform lexicographical string comparison using XPath. This section takes a look at how to use XSD extension functions to select and process nodes based on their XSD data type. This example consists of the following pieces.

books.xsd
The XSD schema that is used to validate the books.xml file.
books.xml
The file that is loaded and validated against the books.xsd schema.
Microsoft Visual Basic example code

This Visual Basic example code:

  • Creates an XMLSchemaCache object.
  • Adds the schema to the XMLSchemaCache object.
  • Creates a DOMDocument object and sets the schemas property to reference the books.xsd schema. The example code also sets the SelectionLanguage and SelectionNamespaces properties on the DOMDocument object.
  • Uses the XSD type-local-name function to select a node based on it's data type.
  • Uses the XSD type-is function to return a node list that contains nodes only of the data type string.

To get started

  1. Open Visual Basic 6.0, and in the New Project dialog box, double-click Standard EXE.
  2. On the Project menu, click References.
  3. In the Available References list, select Microsoft XML,v4.0, and then click OK.
  4. Add a Command button to Form1.
  5. Save the project to a folder on your hard drive.

The XML Document (books.xml)

The books.xml file used in this example, shown below, is a modified version of the books.xml file used throughout the MSXML SDK. Notice that "urn:books" is declared as the default namespace for this document.

If you want to run the example in this topic, copy the following code to a text editor, such as Notepad, and then save the file as books.xml.

<?xml version="1.0"?>
<x:catalog xmlns:x="urn:books">
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications with
      XML.</description>
      <title>2000-10-01</title>
   </book>
</x:catalog>

The XSD Schema (books.xsd)

The following document shows the books.xsd schema used in this example.

If you want to run the example in this topic, copy the following code to a text editor, such as Notepad, and then save the file as books.xsd.

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="catalog" type="CatalogData"/>

  <xsd:complexType name="CatalogData">
    <xsd:sequence>
      <xsd:element name="book" type="bookdata" minOccurs="0"
      maxOccurs="unbounded"/>
      </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="bookdata">
    <xsd:sequence>
      <xsd:element name="author" type="xsd:string"/>
      <xsd:element name="title" type="xsd:string"/>
      <xsd:element name="genre" type="xsd:string"/>
      <xsd:element name="price" type="xsd:float"/>
      <xsd:element name="publish_date" type="xsd:date"/>
      <xsd:element name="description" type="xsd:string"/>
    </xsd:sequence>
    <xsd:attribute name="id" type="xsd:string"/>
  </xsd:complexType>
</xsd:schema>

Visual Basic XSD Extension Function Code

The following code snippet shows how you can use XSD extension functions to return nodes based on their XSD data type. This example code uses the type-is function to return the first string data type in the document and the type-local-name function to return a list of nodes of the string data type.

The Visual Basic code creates an XMLSchemaCache40 object, adds the namespace URI declaration ("urn:books") and the schema (books.xsd) to the object, and then references the schema using the schemas property of the DOMDocument object. Notice in the code that the SelectionLanguage property is set to XPath and the SelectionNamespaces property is set to "xmlns:ms='urn:schemas-microsoft-com:xslt" enabling the ms: namespace prefix to be used. the Validation is performed when the books.xml file is loaded into the DOMDocument object. Validation errors are returned using the parseError property of the DOMDocument object.

To run the example

  1. Copy the code shown below to the Command1_Click procedure. It should look like the code in the code snippet below when you are done.
  2. On the Visual Basic toolbar, click Start, and then click the Command1 button on form1.

When you run the example, the Set objElem = xmldom.documentElement.selectSingleNode("//*[ms:type-local-name()='string']") statement returns the first node of the type string. The node name of the returned node is displayed in a message box. The Set objNodeList = xmldom.selectNodes "//*[ms:type-is('http://www.w3.org/2001/XMLSchema','string')]") statement returns a list of nodes of data type string. The For/Next loop interates through the nodes and displays the text of each node in a message box.

Private Sub Command1_Click()
Dim xmlschema As MSXML2.XMLSchemaCache
Set xmlschema = New MSXML2.XMLSchemaCache
Dim xmldom As MSXML2.DOMDocument
Set xmldom = New MSXML2.DOMDocument
Dim objElem As IXMLDOMNode
Dim objNodeList As IXMLDOMNodeList

xmlschema.Add "urn:books", App.Path & "\books.xsd"
Set xmldom.schemas = xmlschema

xmldom.setProperty "SelectionLanguage", "XPath"
xmldom.setProperty "SelectionNamespaces", "xmlns:ms='urn:schemas-microsoft-com:xslt'"

xmldom.async = False
xmldom.Load App.Path & "\books1.xml"

'returns the first node in the document with the string data type
Set objElem = xmldom.documentElement.selectSingleNode _
                ("//*[ms:type-local-name()='string']")
MsgBox objElem.nodeName

'returns a list of nodes with the string data type
Set objNodeList = xmldom.selectNodes _
    ("//*[ms:type-is('http://www.w3.org/2001/XMLSchema','string')]")
For i = 0 To (objNodeList.length - 1)
    MsgBox objNodeList.Item(i).Text
Next

If xmldom.parseError.errorCode <> 0 Then
    MsgBox xmldom.parseError.errorCode & " " & xmldom.parseError.reason
Else
    MsgBox "No Error"
End If

End Sub

See Also

Using XSD Extension Functions | XML Schema Examples | XML Schema Element Map | XML Schema Elements | XML Data Types Reference | Primitive XML Data Types | Derived XML Data Types | Data Type Facets | IXMLDOMSchemaCollection/XMLSchemaCache

Other Resources Other Resources

World Wide Web Consortium (W3C) XML Schema Part 2: Datatypes | World Wide Web Consortium (W3C) XML Schema Part 1: Structures


ms:type-is Function

[This is preliminary documentation and subject to change.]

Compares the current node's data type with the XSD data type specified in the arguments.

boolean ms:type-is(string URI, string local-name)

Parameters

string URI
The namespace URI for the data type against which the current data type is evaluated.
string local name
The local name of the data type against which the current data type is evaluated.

Remarks

Returns false if an XSD data type is not available or the XSD data type has no name. This function is aware of XSD inheritence, so that if type "b" is derived from "a", then for the node of type "b", type-is("http://www.example.com/catalog", "a") returns true. The following sample expression selects all nodes with the data type "string" or data types derived from it.

"//*[ms:type-is('www.w3.org/2001/XMLSchema','string')]">

See Also

Using XSD Extension Functions | Data Types in Schemas | XSD Schema Reference | XML Data Types Reference (XSD)


ms:type-local-name([node-set]) Function

[This is preliminary documentation and subject to change.]

Returns the nonqualified name of the XSD type of the current node or the first node (in document order) in the provided node-set.

string ms:type-local-name([node-set])

Remarks

For simple types, the type-local-name function returns a name such as "ID" or "ENTITY". For complex XSD types that have the name attribute specified, the type-local-name returns a nonqualified name such as "Class".

The following sample expression selects all nodes with the XSD built-in primitive data type "string".

"//*[ms:type-local-name()='string')]"

See Also

Using XSD Extension Functions | Data Types in Schemas | XSD Schema Reference | XML Data Types Reference (XSD)


ms:type-namespace-uri ([node-set]) Function

Microsoft XML 4.0 Technology Preview - XSLT Reference

ms:type-namespace-uri([node-set]) Function

[This is preliminary documentation and subject to change.]

Returns the namespace URI associated with the XSD data type of a current node or the first node (in document order) in the provided node-set.

string ms:type-namespace-uri([node-set])

Remarks

For simple XSD types, the type-namespace-uri function returns an empty string. For complex XSD types that have the name attribute specified, the type-namespace-uri function returns a complete URI such as "http://www.example.com/my-xsd-types."

The following sample expression returns nodes whose data type has a namespace URI of "PurchaseOrderType".

"//*[ms:type-namespace-uri()='uri:PurchaseOrderType')]"

See Also

Using XSD Extension Functions | Data Types in Schemas | XSD Schema Reference | XML Data Types Reference (XSD)


ms:string-compare Function

[This is preliminary documentation and subject to change.]

Performs string comparison. This function is necessary because two strings cannot be compared lexicographically using XPath.

number ms:string-compare(string x, string y, [,string language _
                                             [,string options]])

Parameters

string x
String value for comparison. Nonstring values are converted to a string value before comparison.
string y
String value for comparison. Nonstring values are converted to a string value before comparison.
string language [optional]
Defines the language to determine the sort order. This is similar to the <xsl:sort> "lang" attribute (for example, "en-US" or "fr-CA"). If this parameter is omitted or an empty string, the language is defined by the system environment (language of the current thread).
string options [optional]
By default, comparison is case-sensitive, with lowercase first.

option | description
-u | Makes the comparison case-sensitive, uppercase first.
-i | Makes the comparison case-insensitive so that uppercase and lowercase have no meaning.

Remarks

If a language or option is specified that is not supported, a runtime error occurs. For MSXML components, E_FAIL is returned.

Example

number ms:string-compare(string x, string y)

If | The example function returns
x < y | -1
x = y | 0
x > y | 1

See Also

Data Types in Schemas | XSD Schema Reference | XML Data Types Reference (XSD)


ms:schema-info-available Function

[This is preliminary documentation and subject to change.]

Returns true if XSD information is available for the current node.

boolean ms:xsd-info-available()

Remarks

The following expression returns true for all nodes with XSD-type information.

"//[ms:schema-info-available()]"

See Also

Using XSD Extension Functions | Data Types in Schemas | XSD Schema Reference | XML Data Types Reference (XSD)


ms:utc Function

[This is preliminary documentation and subject to change.]

Converts date/time related values into Coordinated Universal Time and into a fixed (normalized) representation that can be sorted and compared lexicographically.

string ms:utc(string)

Remarks

This function works only with time instances such as timeInstant, time, date, yearMonth, year, monthDay, day, and month. The utc function does not work with periods of time such as timeDuration or its derived types. For nonstring arguments, this function acts as if a string function were first applied. This function does not depend on the presence of XSD information. If a string cannot be interpreted as a valid XSD date/time-related format, it returns an empty string. The rules for date/time values are:

  • string is interpreted as a time-related XSD format and converted to format:

    YYYY-MM-DD T HH:NN:SS.III

    where

    Characters | Represents
    YYYY | a four digit year (for example, 2001)
    MM | the number of a month (for example, 01 for January)
    DDD | a day of a month. Three digits are used to accommodate the ability to point out the exact day of the year (for example, "2001-04-123." 123 points out the 123rd day of the year.)
    HH | a two-digit hour (for example, "00-23")
    SS | seconds (for example, "00-59")
    III | milliseconds (for example, "000-999") If no milliseconds are specified, dashes representing milliseconds are "right-truncated."

  • For negative time and years beyond 9999, the utc function returns an empty string because negative timeInstances, periods, invalid Gregorian dates and other cases described in the following string constraints section will not be able to compare correctly.
  • Fields indicating recurrence are replaced with the same number of "-" characters.
  • Unspecified fields are replaced with "-" characters.

String Comparison Constraints:

  • Lexicographical comparison does not work for sets of mixed AC and BC dates, and gives a reverse order for BC dates. Lexicographical comparison does not work for years greater than 9999.

See Also

Data Types in Schemas | XSD Schema Reference | XML Data Types Reference (XSD)


ms:namespace-uri Function

[This is preliminary documentation and subject to change.]

Resolves the prefix part of a qualified name into a namespace URI.

string ms:namespace-uri(string)

Remarks

The ms:namespace-uri() function assumes that the parameter is a qualified name (for example, "q:mine" or "coffee:beans") and attempts to resolve its prefix in the context of the current node. If the argument is not a qualified name or a noncolon name, this function returns an empty string. For nonstring arguments, this function behaves as if a string function were applied.

See Also

Data Types in Schemas | XSD Schema Reference | XML Data Types Reference (XSD)


ms:local-name Function

[This is preliminary documentation and subject to change.]

Resolves the prefix part of a qualified name into a namespace URI.

string ms:local-name(string)

Remarks

The ms:local-name() function assumes that the parameter is a qualified name (for example, "q:mine" or "coffee:beans") and returns the local name within the context of the current node. If the argument is not a qualified name or a noncolon name, this function returns an empty string. For nonstring arguments, this function behaves as if a string function were applied.

See Also

Data Types in Schemas | XSD Schema Reference | XML Data Types Reference (XSD)


ms:number Function

[This is preliminary documentation and subject to change.]

Takes a string argument in XSD format and converts it into an XPath number.

number ms:number(string)

Remarks

The ms:number function performs conversion the same way as the native XPath number() function, with the exceptions that the ms:number() function converts "-INF" and "INF" into minus and plus infinity, and mathmetical notation such as (1.2e-3) into numbers, not NaNs. For a complete set of numberic formats that can be processed, see the XSD Specification. If the ms:number function is unable to convert a string, it returns a NaN.

See Also

Data Types in Schemas | XSD Schema Reference | XML Data Types Reference (XSD)


ms:format-date Function

[This is preliminary documentation and subject to change.]

Converts standard XSD date formats to characters suitable for output.

string ms:format-date(string datetime, string format [,locale])

Parameters

string datetime
contains a date-related value in XSD format. For nonstring arguments, this function behaves as if a string() function were applied. If the argument is not a date, the output is an empty string. If it is a valid XSD date and some fields are emtpy, this function attempts to fill unspecified fields.
string format
Contains a format string, according to Win32 API GetDateFormat functions.
locale [optional]
Defines the locale to format the data for (for example, "EN_us").

Remarks

The following lists the format characters for ms:format-date.

Character(s) | Description
M | Months as 1-12
MM | Months as 01-12
MMM | Months as Jan-Dec
MMMM | Months as January-December
d | Days as 1-31
dd | Days as 01-31
ddd | Days as Sun-Sat
dddd | Days as Sunday-Saturday
y | Years as 1,2 …,99
yy | Years as 1900-9999
yyyy | Years as 1900-9999
gg | Period/era (ignored if there isn't one)

Note that his format does not allow time zones; does not allow the inclusion of abitrary text into the formatted string; does not allow centuries; does not allow suffixes like May 2cd or April 1st.

See Also

Data Types in Schemas | XSD Schema Reference | XML Data Types Reference (XSD)


ms:format-time Function

[This is preliminary documentation and subject to change.]

Converts standard XSD time formats to characters suitable for output.

string ms:format-date(string datetime, string format [,locale])

Parameters

string datetime
Contains a time-related value in XSD format. For nonstring arguments, this function behaves as if a string() function were applied. If the argument is not a time, the output is an empty string. If it is a valid XSD time and some fields are empty, this function attempts to fill unspecified fields.
string datetime
Contains a format string, according to Win32 API GetTimeFormat functions.
locale [optional]
Defines the locale to format the data for (for example, "EN_us").

Remarks

The following lists the format characters for ms:format-time.

Character(s) | Description
h | Hours as 0-12
hh | Hours as 00-12
H | Hours as 0-23
HH | Hours as 00-23
m | Minutes as 0-59
mm | Minutes as 00-59
s | Seconds as 0-59
ss | Seconds as 00-59
tt | Insert AM or PM, display hurs as 12-hour clock
t | Insert A or P, display hours as 12-hour clock

See Also

Data Types in Schemas | XSD Schema Reference | XML Data Types Reference (XSD)


SAX2 Developer's Guide

This guide introduces the Microsoft COM implementation of SAX2, the latest version of the Simple API for XML. SAX2 is a publicly developed standard for event-based parsing of XML documents. This guide, along with the reference material that accompanies it, describes the Microsoft COM implementation of the SAX2 standard. The Microsoft SAX2 implementation provides both Microsoft® Visual Basic® and Microsoft Visual C++® interfaces.

The following topics provide more information about creating applications with SAX2.

Topic | Description
Starter Kit | This section explains the benefits of SAX2 and helps you choose between SAX2 and the XML Document Object Model (DOM). This section also offers ideas for building SAX2 applications.
Concepts | This section introduces some of the fundamental concepts pertinent to events-based parsing.
How Do I | This section helps you build SAX2 applications. It provides tutorials for using events-based parsers with applications that range from simple searches to more complex chain filtering and atomic lookups.

See Also

SAX2 Reference


Starter Kit

This starter kit is designed to provide tools and information for the latest version of the Simple API for XML (SAX2).

What is SAX?

Frequently Asked Questions About SAX2

JumpStart for Creating a SAX2 Application

Creating C++ Applications Using SAXAppWizard


What is SAX?

The Simple API for XML (SAX) is a publicly developed standard for the events-based parsing of XML documents. SAX defines an abstract programmatic interface that models the XML information set (infoset) through a linear sequence of familiar method calls.

Although SAX and DOM may seem different, each is simply a different projection of the XML infoset onto programmatic types. Because SAX does not demand resources for an in-memory representation of the document, it is a good alternative to the Document Object Model (DOM). SAX facilitates the search of large documents to extract small pieces of information and allows you to abort processing after the information is located. SAX can be used to build DOM trees (or portions of DOM trees); conversely, developers can traverse DOM trees and emit SAX streams.

However, the performance benefits of SAX come at a price. For example, in the case of advanced queries, SAX can be burdensome because of the complexities involved in managing context during processing. In these cases, most developers use the DOM or some combination of SAX and DOM.

SAX support in the latest version of the Microsoft® XML Parser (MSXML) includes methods for completing transformations and validation, which result in better messaging support for end users. This improves server-side transformations of documents as small as 10-20 kilobytes (KB) and the processing of documents of 1 megabyte (MB) or more.

See Also

Why Should I Use SAX? | Frequently Asked Questions About SAX2

Other Resources Other Resources

Megginson Technologies


Frequently Asked Questions About SAX2

The following are some frequently asked questions about the Simple API for XML (SAX).

What are the system requirements for SAX2?

Can I pass a BSTR instead of a URL to the SAXXMLReader?

Does SAX support validation?

Why is white space reported as characters()? Why isn't ignorableWhitespace called?

How do I get XML header information?

How can I use SAXXMLWriter from scripts?

Can I continue parsing if my Visual Basic program breaks because the XML file has errors?

Can I use the same instance of SAXXMLReader to parse XML files sequentially?

How can I write from SAXXMLWriter in a memory buffer in nonUnicode encoding?

How can I reset SAXXMLWriter to create a new string?

How do I avoid appending an XML document to the previous one?

How can I tell if attribute values have an entity reference?

Can I find the order of element attributes?

How do I handle errors with SAX?

What are the system requirements for SAX2?

The system requirements for SAX2 are the same as those for running MSXML.

  • Windows-compatible PC
  • Microsoft Windows® 2000, Microsoft Windows NT 4.0, Microsoft Windows 98, or Microsoft Windows 95

Return to top

Does SAX support validation?

No. At this time SAX does not support validation.

Return to top

Can I pass a BSTR, instead of a URL, to the SAXXMLReader?

You can pass a VARIANT containing a BSTR to ISAXXMLReader::parse(VARIANT). In this case, the encoding is UTF-16.

Return to top

Why is white space reported as characters()? Why isn't ignorableWhitespace called?

White space can occur in several places, for example, in an element without character data, which contains only child nodes and white space. To ignore white space, the parser must be able to distinguish those cases. The SAX parser is a nonvalidating parser and cannot distinguish those cases, so ignorableWhitespace() never gets called. Nonvalidating parsers treat all white space between elements as characters.

Return to top

How do I get XML header information?

The XML header contains version and encoding information, for example, <?xml version="1.0" encoding="UTF-8"?>. To get XML header information, call ISAXXMLReader::getProperty([in] const wchar_t * pwchName, [out, retval] VARIANT * pvarValue); and pass one of following three property values:

"xmldecl-encoding"
"xmldecl-version"
"xmldecl-standalone"
Note The "xmldecl-encoding", "xmldecl-version", and "xmldecl-standalone" properties provide information about the presence and content of the XML header. The information is available only when SAXXMLReader reads and parses the XML document. After processing, the control returns to the application, and this information is no longer available.

XML header information was designed for low-level reader and parser use, not for applications.

To get the processing instruction, implement a ContentHandler that supports ISAXContentHandler and handles the processingInstruction event.

Return to top

How can I use SAXXMLWriter from scripts?

SAXXMLReader implements IVBSAXXMLReader, which is accessible from scripts. You can call handler events directly from SAXXMLWriter and generate XML without the reader.

Return to top

Can I continue parsing if my Visual Basic program breaks because the XML file has errors?

All parser errors are fatal (E_FAIL). However, the classification of parsing errors in SAX is independent from the classification of errors in Microsoft® Visual Basic®. In SAX, a fatal parsing error means only that parsing cannot continue; in Visual Basic, a fatal error means that the application cannot continue. Use the ON ERROR statement in Visual Basic.

Return to top

Can I use the same instance of SAXXMLReader to parse XML files sequentially?

You can use the same instance of SAXXMLReader to parse two XML files sequentially, but not in different threads. The MSXML implementation does not support multithreaded use. AddRef/Release are not multithread-safe and there is no locking on any of the API entry points.

However, you can use two instances of SAXXMLReader in two threads, and parse two different XML files, as long as nothing gets shared.

Return to top

How can I write from SAXXMLWriter in a memory buffer in nonUnicode encoding?

If "memory buffer" is a Visual Basic string, you cannot write to it because it is always in Unicode format. However, you can provide an IStream/ISequentialStream object, which writes to a memory buffer. XML will be generated the same way as for output into a file.

Return to top

How can I reset SAXXMLWriter to create a new string?

To reset SAXXMLWriter to create a new string:

  1. Generate an XML document.
  2. Use a string object from the writer.
  3. Generate another XML document.

Return to top

How do I avoid appending a new XML document to the previous one?

To reset XML writer to create a new string, reset the output property. Internally, the flush method of IMXXMLWriter will be called.

Return to top

How can I tell if attribute values have an entity reference?

There is no indication of whether attribute values have an entity reference.

Return to top

Can I find the order of element attributes?

The order of attributes is not important in XML, and is therefore not exposed. Enumeration with attributes may follow the original order of the attributes.

Return to top

How do I handle errors with SAX?

ISAXErrorHandler/IVBSAXErrorHandler provides the basic interface for handling parsing errors. Currently, all errors are fatal.

In C++, a fatal error will result in returning a value other than S_OK HRESULT from the parse or parseURL method.

In Visual Basic, the On Error statement handles exceptions.

Note The SAX2 reader passes string values to ISAXErrorHandler methods by reference, rather than value. In Visual C++, memory allocation must be freed properly to avoid memory leaks.

Return to top


JumpStart for Creating a SAX2 Application

This section provides a hands-on introduction to the latest version of the Simplified API for XML (SAX2) and includes a step-by-step process for creating a basic SAX2 application. This section provides two tutorials:

  • JumpStart for Creating a SAX2 Application with Visual Basic
  • JumpStart for Creating a SAX2 Application with C++


JumpStart for Creating a SAX2 Application with Visual Basic

To help you get started building Simple API for XML (SAX2) applications with Microsoft® Visual Basic®, this section shows you how to quickly build an application that uses SAX2 to read an XML document and print the document's contents to a text box.

To run this tutorial, you will need the following:

  • The Microsoft XML Parser (MSXML) version 3.0 or later.
  • Visual Basic 6.0.

You can download the JumpStart application from the Other Resources MSDN Code Center. This downloadable version contains more files and differs slightly from the sample application covered in this topic.

This section includes the following topics:

  • Overview of the JumpStart Application
  • Implementing the ContentHandler
  • Implementing the ErrorHandler
  • Creating the Main Form


Overview of the JumpStart Application (Visual Basic)

The Simple API for XML (SAX2) is a push-model parser. When SAX2 parses a document, the SAXXMLReader (reader) reads the document and passes a series of events to the implemented event handlers. The SAX2 reader generates several categories of events, including:

  • those that occur in the content of an XML document.
  • those that occur in the document type definition (DTD).
  • those that occur as errors.

To handle such events, you implement a corresponding handler class that contains methods to process the appropriate events. You implement handlers only for those events you wish to process. If you do not implement a handler for a specific type of event, the reader simply ignores that event.

The JumpStart application covered in this section contains the three components that you most often implement for SAX2 applications in Microsoft® Visual Basic®.

Component | Description
ContentHandler | Implements the IVBSAXContentHandler interface. The ContentHandler is a class that provides methods for processing the main content of an XML document. When SAX2 parses a document, the reader passes a series of events to the ContentHandler. For example, for each element in a document, the reader passes the startElement, characters, and endElement events. To handle these events, you add code to the methods in the ContentHandler to process the information passed by the reader.
ErrorHandler | Implements the IVBSAXErrorHandler interface. The ErrorHandler is a class that provides methods for processing error events passed by the reader. At this time, the reader invokes the fatalError method only.
main form | Provides the user interface for the application. This consists of two text boxes, one for entering a file name and another for displaying results. This interface also has Parse and Exit buttons. In addition to providing the user interface, the main form also contains code that creates instances of the SAXXMLReader, ContentHandler, and ErrorHandler; sets the handler classes to the reader; sets the source for parsing the document; and starts the parse operation.


Implementing the ContentHandler (Visual Basic)

For the JumpStart application, you create the ContentHandler by adding a class that implements the IVBSAXContentHandler interface. Although creating a class may sound complex, Microsoft® Visual Basic® automates most of the process.

Opening a New Project

Before you can create a class based on the IVBSAXContentHandler interface, you must create a new project and then reference that project to the Microsoft XML Parser (MSXML).

To create a new project

  • Open Visual Basic 6.0 and, in the New Project dialog box, double-click Standard EXE.

Referencing MSXML

You must now instruct your application to use the MSXML2 type library provided with MSXML 4.0.

To create a reference to MSXML 4.0

  1. On the Project menu, click References.
  2. In the Available References list, select Microsoft XML, v4.0, and then click OK.

Creating and Implementing the Handler Class

You are now ready to create and implement the new ContentHandler class.

To create a new class

  1. On the Project menu, click Add Class Module.
  2. In the Add Class Module dialog box, double-click Class Module.
  3. On the View menu, select Properties Window.
  4. In the Properties Window, enter ContentHandlerImpl for the Name property.

To implement the ContentHandlerImpl Class

  1. In the Class Window, type Implements, and then press the space bar.

    A drop down list appears with the all the available classes. (This list includes interfaces that are actually abstract classes.)

  2. In the drop-down list, double-click IVBSAXContentHandler. This is the interface you implement to create the ContentHandlerImpl class.
  3. In the Object drop-down list on the left side of the Class Window, click IVBSAXContentHandler.

    This automatically adds code to the Class Window.

  4. In the Procedure drop-down list on the right-hand side of the Class Window, select the IVBSAXContentHandler method or property that you want to add to this class. (You have to select each method even though you do not need to add code to each one.)

    For example, select startElement to add this method to the ContentHandlerImpl class. (When parsing an XML document, the reader will invoke this method each time it encounters a new element in the document.) After you select startElement from the list, the following code appears in the Class Window:

    Private Sub IVBSAXContentHandler_startElement _
                         (strNamespaceURI As String, _
                          strLocalName As String, _
                          strQName As String, _
                          ByVal oAttributes As MSXML2.IVBSAXAttributes)
End Sub
  5. To enable the method or event selected in step 4 to handle the corresponding event, you need to add the appropriate code to that method or property.

    For the startElement method added in step 4, enter the code required to make the method look like this:

    Private Sub IVBSAXContentHandler_startElement _
                          (strNamespaceURI As String, _
                           strLocalName As String, _
                           strQName As String, _
                           ByVal attributes As MSXML2.IVBSAXAttributes)
    Dim i As Integer

    Form1.Text2.text = Form1.Text2.text & "<" & strLocalName

    For i = 0 To (attributes.length - 1)
        Form1.Text2.text = Form1.Text2.text & " " _
        & attributes.getLocalName(i) & "=""" _
        & attributes.getValue(i) & """"
    Next

    Form1.Text2.text = Form1.Text2.text & ">"

    If strLocalName = "qu" Then
        Err.Raise vbObjectError + 1, "ContentHandler.startElement", _
                                     "Found element <qu>"
    End If

End Sub
  6. To handle additional events passed by the reader, repeat steps 4 and 5 for each method or property that you want to add to the ContentHandlerImpl class.

Complete Code for the ContentHandlerImpl Class

The preceding instructions explain how to create a new project with a reference to Microsoft XML, v4.0, and how to create a ContentHandler class called ContentHandlerImpl by implementing the IVBSAXContentHandler interface. The following shows the complete code for the ContentHandlerImpl class.

Option Explicit

Implements IVBSAXContentHandler

Private Sub IVBSAXContentHandler_startElement _
                     (strNamespaceURI As String, _
                      strLocalName As String, _
                      strQName As String, _
                      ByVal attributes As MSXML2.IVBSAXAttributes)

    Dim i As Integer

    Form1.Text2.text = Form1.Text2.text & "<" & strLocalName

    For i = 0 To (attributes.length - 1)
        Form1.Text2.text = Form1.Text2.text & " " & _
                           attributes.getLocalName(i) & "=""" & _
                           attributes.getValue(i) & """"
    Next

    Form1.Text2.text = Form1.Text2.text & ">"

    If strLocalName = "qu" Then
        Err.Raise vbObjectError + 1, "ContentHandler.startElement", _
                                     "Found element <qu>"
    End If

End Sub

Private Sub IVBSAXContentHandler_endElement(strNamespaceURI As String, _
                                            strLocalName As String, _
                                            strQName As String)

    Form1.Text2.text = Form1.Text2.text & "</" & strLocalName & ">"

End Sub

Private Sub IVBSAXContentHandler_characters(text As String)
    text = Replace(text, vbLf, vbCrLf)
    Form1.Text2.text = Form1.Text2.text & text

End Sub

Private Property Set IVBSAXContentHandler_documentLocator(ByVal RHS As _
                                                    MSXML2.IVBSAXLocator)

End Property

Private Sub IVBSAXContentHandler_endDocument()

End Sub

Private Sub IVBSAXContentHandler_endPrefixMapping(strPrefix As String)

End Sub

Private Sub IVBSAXContentHandler_ignorableWhitespace(strChars As String)

End Sub

Private Sub IVBSAXContentHandler_processingInstruction(target As String, _
                                                       data As String)

    Form1.Text2.text = Form1.Text2.text & "<?" & target & " " _
                       & data & ">"

End Sub

Private Sub IVBSAXContentHandler_skippedEntity(strName As String)

End Sub

Private Sub IVBSAXContentHandler_startDocument()

End Sub

Private Sub IVBSAXContentHandler_startPrefixMapping(strPrefix As String, _
                                                    strURI As String)

End Sub

As you can see from the sample code, not all methods or properties have custom code added to them. When you implement a handler for the Simple API for XML (SAX2), you can add only the methods or properties that you need.

In the next section, you create the ErrorHandler for the JumpStart application.


Implementing the ErrorHandler

For the JumpStart application, you create the ErrorHandler by implementing the IVBSAXErrorHandler interface.

To create the ErrorHandlerImpl class

  1. On the Project menu, click Add Class Module.
  2. In the Add Class Module dialog box, double-click Class Module.
  3. On the View menu, select Properties Window.
  4. In the Properties Window, enter ErrorHandlerImpl for the Name property.

To implement the ErrorHandlerImpl class

  1. In the Class Window, type Implements, press the spacebar, and then double-click IVBSAXErrorHandler from the drop-down list that appears.
  2. In the Object drop-down list on the left side of the Class Window, select IVBSAXErrorHandler.
  3. In the Procedure drop-down list on the right side of the Class Window, select a method or property to add to the class.
  4. Add the desired code to the selected method or property.
  5. Repeat steps 3 and 4 until you have added the desired methods and properties.
Note If you have trouble implementing methods and procedures for the ErrorHandlerImpl class, refer back to Implementing the ContentHandler to see how methods and properties were implemented for the ContentHandlerImpl class.

Complete Code for the ErrorHandlerImpl Class

The following is the complete code for the ErrorHandlerImpl class of the JumpStart application.

Option Explicit

Implements IVBSAXErrorHandler

Private Sub IVBSAXErrorHandler_fatalError(ByVal lctr As IVBSAXLocator, _
                                          msg As String, _
                                          ByVal errCode As Long)
    Form1.Text2.text = Form1.Text2.text & "*** error *** " & msg

End Sub

Private Sub IVBSAXErrorHandler_error(ByVal lctr As IVBSAXLocator, _
                                     msg As String, ByVal errCode As Long)
End Sub

Private Sub IVBSAXErrorHandler_ignorableWarning( _
                                 ByVal oLocator As MSXML2.IVBSAXLocator, _
                                 strErrorMessage As String, _
                                 ByVal nErrorCode As Long)
End Sub

In the preceding code, only the fatalError method contains code for handling events. For this version of the Microsoft® XML Parser (MSXML), only the fatalError method is called for IVBSAXErrorHandler.


Creating the Main Form

The main form provides the user interface for the JumpStart application and consists of four elements.

Interface Element | Description
Text1 | A text box for entering the file name of the file to parse.
Command1 | A button to start the parse process.
Command2 | A button to exit the application.
Text2 | A text box that displays the results of the parse operation.

In addition to providing the interface elements, the main form also provides code that creates the required instances of the classes and starts the parse process.

To | The main form uses this code
Create an instance of the reader (SAXXMLReader) | Dim reader As New SAXXMLReader
Create an instance of ContentHandlerImpl and set it to receive events from the reader | Dim contentHandler As New ContentHandlerImpl Set reader.contentHandler = contentHandler
Create an instance of ErrorHandlerImpl and set it to receive events from the reader | Dim errorHandler As New ErrorHandlerImpl Set reader.errorHandler = errorHandler
Start the parse process | reader.parseURL (Text1.text)

Complete Code for the Main Form

The following shows the complete code for the main form of the JumpStart application.

Option Explicit

Private Sub Command1_Click()

    Dim reader As New SAXXMLReader    'Reads the XML document
    Dim contentHandler As New ContentHandlerImpl 'Receives parsing events
    Dim errorHandler As New ErrorHandlerImpl        'Receive error events
    Text2.text = ""
    Set reader.contentHandler = contentHandler    'They work together
    Set reader.errorHandler = errorHandler        'They also work together
    On Error GoTo 10
    reader.parseURL (Text1.text)               'Parse the document

    Exit Sub                                   'That's all, folks!

10: Text2.text = Text2.text & "*** Error *** " & Err.Number _
                 & " : " & Err.Description
End Sub

Private Sub Command2_Click()
    End
End Sub

The Exit Sub and line marked 10: are required only if you want to handle processing outside the ErrorHandler. Otherwise, you can use On Error Resume Next.

To run the JumpStart application

  1. Download the JumpStart application, available from the Other Resources MSDN Code Center, to your computer.
  2. On your computer, double-click VBSAXExample.exe.
  3. In the File name box, type Test.xml and then click Parse. The JumpStart application parses the file and displays the results in the Text2 text box.

You can use this introduction to the Simple API for XML (SAX2) as a starting point for writing your own applications. For more information about the Microsoft® XML Parser (MSXML) implementation of the SAX2 interfaces, see the SAX2 Reference.


JumpStart for Creating a SAX2 Application with C++

As a quick introduction to how the Microsoft® XML Parser (MSXML) implements the Simple API for XML (SAX2), and to help you get started building applications using the SAX2 interfaces, this section shows you how to build a basic C++ application that reads an XML document and prints the document's tags to the console.

To run this tutorial, you will need the following:

  • The Microsoft XML Parser (MSXML) version 3.0 or later.
  • The JumpStart application, available from the Other Resources MSDN Code Center.

This section includes the following topics:

  • Overview of the JumpStart Application
  • Implementing the ContentHandler
  • Creating the Header File
  • Creating the MyContent Class
  • Creating the Main Program


Overview of the JumpStart Application (C++)

The Simple API for XML (SAX2) is a push-model parser. When SAX2 parses a document, the SAXXMLReader (reader) reads the document and passes a series of events to the event handlers that you implement. The SAX2 reader generates several categories of events, including:

  • those that occur in the content of an XML document.
  • those that occur in the document type definition (DTD).
  • those that occur as errors.

To handle such events, you implement a corresponding handler class that contains methods to process the appropriate events. You implement handlers only for those events you wish to process. If you do not implement a handler for a specific type of event, the reader simply ignores that event.

You implement two main components in this JumpStart application.

Component | Description
ContentHandler | Implements the ISAXContentHandler interface. The ContentHandler is a class that provides methods for processing the main content of an XML document. When SAX2 parses a document, the reader passes a series of events to the ContentHandler. For example, for each element in a document, the reader passes startElement, characters, and endElement events. You handle these events by adding code to the methods in the ContentHandler to process the information passed by the reader.
main program
  • Creates an instance of ISAXXMLReader (reader).
  • Creates an instance of the ContentHandler.
  • Sets the ContentHandler to the reader.
  • Sets the source for the XML document.
  • Starts the parsing process.

To create the JumpStart application, you must first implement a handler class extending the ISAXContentHandler interface. With C++, you can create a class and not a full-featured COM object. In the methods of this class, you tell the application what to do when it receives notification of an event. After you implement the ContentHandler class, you create the main program that creates an instance of the SAXXMLReader, sets the ContentHandler, and starts the parse operation.


Implementing the ContentHandler (C++)

The first step when creating a Simple API for XML (SAX2) application is to implement handler classes. This example implements only the ContentHandler that is derived from the ISAXContentHandler interface. Implementing the ContentHandler is described in the following topics.

  • Creating the Header File
  • Creating the MyContent Class


Creating the Header File

When it comes to using the Simple API for XML (SAX2), the most useful handler class is the ContentHandler. You derive this class from the ISAXContentHandler interface.

To use the SAX2 interfaces in the Microsoft® XML Parser (MSXML), you must declare them with the following code.

#import <msxml3.dll> raw_interfaces_only
using namespace MSXML2;
Note For the JumpStart application, you declare the interfaces in the StdAfx.h file.

To implement the ContentHandler, create the header file, named "MyContent.h", as shown in the following sample code.

#include "SAXContentHandlerImpl.h"

class MyContent : public SAXContentHandlerImpl
{
public:
    MyContent();
    virtual ~MyContent();

        virtual HRESULT STDMETHODCALLTYPE startElement(
            /* [in] */ wchar_t __RPC_FAR *pwchNamespaceUri,
            /* [in] */ int cchNamespaceUri,
            /* [in] */ wchar_t __RPC_FAR *pwchLocalName,
            /* [in] */ int cchLocalName,
            /* [in] */ wchar_t __RPC_FAR *pwchQName,
            /* [in] */ int cchQName,
            /* [in] */ ISAXAttributes __RPC_FAR *pAttributes);

        virtual HRESULT STDMETHODCALLTYPE endElement(
            /* [in] */ wchar_t __RPC_FAR *pwchNamespaceUri,
            /* [in] */ int cchNamespaceUri,
            /* [in] */ wchar_t __RPC_FAR *pwchLocalName,
            /* [in] */ int cchLocalName,
            /* [in] */ wchar_t __RPC_FAR *pwchQName,
            /* [in] */ int cchQName);

        virtual HRESULT STDMETHODCALLTYPE startDocument();

private:
        void prt(
            /* [in] */ const wchar_t * pwchFmt,
            /* [in] */ const wchar_t __RPC_FAR *pwchVal,
            /* [in] */ int cchVal);
      int idnt;
};

#endif // !defined(AFX_MYCONTENT_H__E1B3AF99_0FA6_44CD_82E3_55719F9E3806__INCLUDED_)


Creating the MyContent Class

After you create the MyContent.h file, the next step is to implement the ContentHandler class, named MyContent.

#include "stdafx.h"
#include "MyContent.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

MyContent::MyContent()
{
   idnt = 0;
}

MyContent::~MyContent()
{

}

HRESULT STDMETHODCALLTYPE MyContent::startElement(
            /* [in] */ wchar_t __RPC_FAR *pwchNamespaceUri,
            /* [in] */ int cchNamespaceUri,
            /* [in] */ wchar_t __RPC_FAR *pwchLocalName,
            /* [in] */ int cchLocalName,
            /* [in] */ wchar_t __RPC_FAR *pwchQName,
            /* [in] */ int cchQName,
            /* [in] */ ISAXAttributes __RPC_FAR *pAttributes)
{
   HRESULT hr = S_OK;
   int l;
   printf("\n%*s",3 * idnt++, "");
    prt(L"<%s",pwchLocalName,cchLocalName);
   pAttributes->getLength(&l);
   for ( int i=0; i<l; i++ ) {
      wchar_t * ln, * vl; int lnl, vll;
      pAttributes->getLocalName(i,&ln,&lnl);
      prt(L" %s=", ln, lnl);
      pAttributes->getValue(i,&vl,&vll);
      prt(L"\"%s\"", vl, vll);
   }
   printf(">");

   // A little example, how to abort parse
   if ( wcsncmp(pwchLocalName,L"qu",2) == 0 ) {
      printf("\n<qu> tag encountered, parsing aborted.");
      hr = E_FAIL;
   }

    return hr;
}

HRESULT STDMETHODCALLTYPE MyContent::endElement(
            /* [in] */ wchar_t __RPC_FAR *pwchNamespaceUri,
            /* [in] */ int cchNamespaceUri,
            /* [in] */ wchar_t __RPC_FAR *pwchLocalName,
            /* [in] */ int cchLocalName,
            /* [in] */ wchar_t __RPC_FAR *pwchQName,
            /* [in] */ int cchQName)
{
   printf("\n%*s",3 * --idnt, "");
    prt(L"</%s>",pwchLocalName,cchLocalName);
    return S_OK;
}

HRESULT STDMETHODCALLTYPE MyContent::startDocument()
{
    printf("<?xml version=\"1.0\" ?>");
    return S_OK;
}

void MyContent::prt(
            /* [in] */ const wchar_t * pwchFmt,
            /* [in] */ const wchar_t __RPC_FAR *pwchVal,
            /* [in] */ int cchVal)
{
    static wchar_t val[1000];
    cchVal = cchVal>999 ? 999 : cchVal;
    wcsncpy( val, pwchVal, cchVal ); val[cchVal] = 0;
    wprintf(pwchFmt,val);
}


Creating the Main Program

In this topic, you create a main program that:

  • provides a command prompt interface.
  • creates a parser by instantiating a class that implements the SAXXMLReader interface.
  • creates a ContentHandler by instantiating the MyContent class.
  • registers the ContentHandler with the parser.

Complete Code for the Main Program

The following is the code for the main program.

#include "stdafx.h"

#include "MyContent.h"
#include "SAXErrorHandlerImpl.h"

int main(int argc, char* argv[])
{
   if (argc<2) {
      printf("\nTry something like\n\ttestSax_
      file:///drive:/path/file.xml\nGood luck!\n");
      return 0;   // Need URL to read
   }

   CoInitialize(NULL);
   ISAXXMLReader* pRdr = NULL;

   HRESULT hr = CoCreateInstance(
                        __uuidof(SAXXMLReader),
                        NULL,
                        CLSCTX_ALL,
                        __uuidof(ISAXXMLReader),
                        (void **)&pRdr);

   if(!FAILED(hr))
   {
      MyContent * pMc = new MyContent();
      hr = pRdr->putContentHandler(pMc);

      // No sense to do so in this example, just an illustration how to _
         set other handlers
      //===================================================================================
       SAXErrorHandlerImpl * pEc = new SAXErrorHandlerImpl();
       hr = pRdr->putErrorHandler(pEc);
      // SAXDTDHandlerImpl * pDc = new SAXDTDHandlerImpl();
      // hr = pRdr->putDTDHandler(pDc);

      static wchar_t URL[1000];
      mbstowcs( URL, argv[1], 999 );
      wprintf(L"\nParsing document: %s\n", URL);

      hr = pRdr->parseURL(URL);
      printf("\nParse result code: %08x\n\n",hr);

      pRdr->Release();
   }
   else
   {
      printf("\nError %08X\n\n", hr);
   }

   CoUninitialize();
   return 0;
}

To run the JumpStart application

  1. Download the JumpStart application, available from the Other Resources MSDN Code Center, to your computer.
  2. From the command prompt, type the following:
    pathname\debug\cppsaxsample.exe test.xml.

    where pathname is the name of the folder to which you downloaded the JumpStart application files. The test.xml file is a test file provided with the download. The parsed test.xml file should appear in the command prompt window.

You can use this brief introduction to the Simple API for XML (SAX2) as a starting point for writing your own applications. For more information about the Microsoft® XML Parser (MSXML) implementation of the SAX2 interfaces, see the SAX2 Reference.


Creating C++ Applications Using SaxAppWizard

Programming C++ applications that use SAX can require some extra work. The SAX Win32 AppWizard, available for download from Microsoft® Product Support Services, facilitates programming SAX applications in C++. Included with the download is a sample program created using this wizard.

Note As with other sample code provided as an aid to developers, there is no support plan for the SAX Win32 AppWizard.

Other Resources Other Resources

SAMPLE: SAX Win32 AppWizard Creates a Visual C++ SAX Application


Concepts

The Simple API for XML (SAX) is an events-based parser that provides an alternative to the Document Object Model (DOM). This section introduces some of the fundamental concepts pertinent to SAX and events-based parsing.

How Events-Based Parsing Works

Receiving Events with SAX

Choosing Between SAX and DOM


How Events-Based Parsing Works

To appreciate the benefits of the Microsoft COM implementation of the Simple API for XML (SAX), it helps to understand how you can use SAX2 to process XML documents. The SAX2 parser reads an XML document and generates events based on specific symbols that it encounters in the document. The SAX2 parser does not create a tree structure in memory for the document, although you can programmatically instruct it to do so. Rather, the SAX2 parser processes a document's contents sequentially and generates events as it reads through the document.

When you write an application based on events-based programming, you create functions to respond to user-generated events, such as the OnClick event. Writing an application for an events-based parser is similar. However, in the case of SAX, the parser, not a user, generates the events.

Consider the following simplified document.

<?xml version="1.0"?>
<parts>
<part>TurboWidget</part>
</parts>

As the SAX2 parser processes this document, it generates a sequence of events such as the following.

StartDocument( )
StartElement( "parts" )
StartElement( "part" )
Characters( "TurboWidget" )
EndElement( "part" )
EndElement( "parts" )
EndDocument( )

Think of SAX2 as a push parser. SAX2 generates the events and you implement the event handlers that contain methods to process the events. For more information about event handlers and how to implement them, see JumpStart for Creating a SAX2 Application.


Receiving Events with SAX

[This is preliminary documentation and subject to change.]

The following are the building blocks of a typical SAX application.

SAXXMLReader
SAXXMLReader implements the ISAXXMLReader interface. SAXXMLReader consumes the XML and throws events to the handlers that you set for the reader. First you create an instance of SAXXMLReader, and then set a ContentHandler and an ErrorHandler for receiving events from the reader.
IVBSAXContentHandler
The ContentHandlerImpl.cls class implements the IVBSAXContentHandler interface. IVBSAXContentHandler catches events thrown by the reader. The main events are: startDocument, endDocument, startElement, endElement, and characters.
IVBSAXErrorHandler
The ContentHandlerImpl.cls class implements the IVBSAXErrorHandler interface. IVBSAXErrorHandler catches any errors raised during the read process. At this time, MSXML supports only the fatalError method.
Application
The application consists of code that typically creates an instance of the SAXXMLReader, sets the content handler and error handler for the reader, and then calls the parse or parseURL method of the SAXXMLReader to process an XML file.

See Also

JumpStart for Creating a SAX Application with Visual Basic | JumpStart for Creating a SAX Application with C++ | Create a Simple Filter | IVBSAXXMLReader Interface | IMXWriter Interface | IVBSAXContentHandler Interface | IVBSAXDeclHandler Interface | IVBSAXDTDHandler Interface | IVBSAXErrorHandler Interface | IVBSAXLexicalHandler Interface | output Property


Choosing Between SAX and DOM

The following topics discuss the benefits and tradeoffs of using SAX or DOM to process XML documents.

When Should I Use SAX?

When Should I Use DOM?


When Should I Use SAX?

As an events-based parser that processes documents in a serial manner, the Simple API for XML (SAX) presents an excellent alternative to the Document Object Model (DOM).

When your documents are large

Perhaps the biggest advantage of SAX is that it requires significantly less memory to process an XML document than the DOM. With SAX, memory consumption does not increase with the size of the file. For example, a 100 kilobyte (KB) document can occupy up to 1 megabyte (MB) of memory using the DOM; the same document requires significantly less memory when using SAX. If you must process large documents, SAX is the better alternative, particularly if you do not need to change the contents of the document.

When you need to abort parsing

Because SAX allows you to abort processing at any time, you can use it to create applications that fetch particular data. For example, you can create an application that searches for a part in inventory. When the application finds the part, it returns the part number and availability, and then stops processing.

When you want to retrieve small amounts of information

For many XML-based solutions, it is not necessary to read the entire document to achieve the desired results. For example, if you want to scan data for relevant news about a particular stock, it's inefficient to read the unnecessary data into memory. With SAX, your application can scan the data for news related only to the stock symbols you indicate, and then create a slimmed-down document structure to pass along to a news service. Scanning only a small percentage of the document results in a significant savings of system resources.

When you want to create a new document structure

In some cases, you might want to use SAX to create a data structure using only high-level objects, such as stock symbols and news, and then combine the data from this XML file with other news sources. Rather than build a DOM structure with low-level elements, attributes, and processing instructions, you can build the document structure more efficiently and quickly using SAX.

When you cannot afford the DOM overhead

For large documents and for large numbers of documents, SAX provides a more efficient method for parsing XML data. For example, consider a remote procedure call (RPC) that returns 10 MB of data to a middle-tier server to be passed to a client. Using SAX, the data can be processed using a small input buffer, a small work buffer, and a small output buffer. Using the DOM, the data structure is constructed in memory, requiring a 10 MB work buffer and at least a 10 MB output buffer for the formatted XML data.


When Should I Use DOM?

The following are some suggestions for when to use DOM.

When there is no random access to the document

Because the document is not in memory, you must handle data in the order in which it is processed. DOM is better in this case; SAX can be difficult to use when the document contains many internal cross-references, such as ID and IDREF attributes.

When you want to implement complex searches

It is your responsibility to maintain data structures holding context information that you must retain, such as the attributes of the current element's ancestor.

No SAX implementation in current browsers

SAX support is not built into Microsoft® Internet Explorer.

When you need to perform XSLT transformations

The DOM works better for XSL Transformations (XSLT) where the source XML document is transformed based on the XSLT template applied. For example, to create multiple views of the same data, you must transform it using one of two style sheets. In order for this transformation to take place, you must also create two instances of the DOM. One stores the XML source; the other stores the transformed content.

When you need complex XPath filtering

Use the DOM if you must perform complex XML Path Language (XPath) filtering and retain complex data structures that hold context information. The tree structure of the DOM retains context information automatically. With SAX, you must retain the context information yourself.

When you want to modify and save XML

The DOM allows you to create or modify a document in memory, as well as read a document from an XML source file. SAX is designed for reading, not writing, XML documents. The DOM is the better choice for modifying an XML document and saving the changed document to memory.

When you need random access to data

If random access to information is crucial, it is better to use the DOM to create a tree structure for the data in memory.


How Do I?

This section provides the following tutorials that demonstrate how to accomplish common SAX tasks.

Create a Simple Filter

Create a DOMDocument Object from SAX Events

Throw SAX Events from a DOM Object

Use MXXMLWriter


Create a Simple Filter

[This is preliminary documentation and subject to change.]

The simple filter example demonstrates how SAX can be used to filter content to create a subset of the original document being parsed. In this example, the application parses books.xml and produces a document fragment that contains only title elements and characters. The application is kept simple to demonstrate the fundamental principles involved in transforming documents with SAX, including:

  • how to detect the presence of an element in an XML document and how to write the element's content to the application's output.
  • the essential SAX methods you must use to conditionally process content.
  • how to set a flag to indicate across events that an element is within scope.
  • how to create a document fragment.

This topic is divided into the following sections:

  • Overview of the Simple Filter Application
  • Application Form
  • How Filter Criteria is Set
  • ContentHandlerImpl Class
  • Essential Handler Methods
  • Run the Application

See Also

Sample XML File (books.xml)


Overview of the Simple Filter Application

[This is preliminary documentation and subject to change.]

The simple filter application contains the building blocks of almost all SAX applications, including:

SAXXMLReader
Coclass that implements the ISAXXMLReader interface. SAXXMLReader consumes the XML and throws events to the handlers that you set for the reader. This example creates an instance of SAXXMLReader, and then sets a ContentHandler and an ErrorHandler for receiving events from the reader.
IVBSAXContentHandler
Catches events thrown by the reader. For this application, the ContentHandlerImpl class implements the IVBSAXContentHandler interface. This application highlights the main events received by the ContentHandler, including startDocument, endDocument, startElement, endElement, and characters.
IVBSAXErrorHandler
Catches any errors raised during the read process. For this application, the ContentHandlerImpl class also implements the IVBSAXErrorHandler interface. At this time, MSXML supports the fatalError method only.

This application consists of two main parts.

Application form
Provides the user interface for the application. This consists of three text boxes: one for entering a file name; one for entering an element name; and the other for displaying results. The form also has Parse and Exit buttons. Pressing Parse creates an instance of the SAXXMLReader; creates an instance of the class implementing the IVBSAXContentHandler and IVBSAXErrorHandler interfaces; and then sets the contentHandler and errorHandler properties of the reader to point to the class. Pressing Parse also sets the filter criteria in the content handler, sets the input for the reader, and starts the parse operation.
ContentHandlerImpl
A class that implements the IVBSAXContentHandler and IVBSAXErrorHandler interfaces. When parsing begins, the reader throws a series of events that are received by an instance of the ContentHandlerImpl class. For example, for each element in a document, the reader throws the startElement, characters, and endElement events. To conditionally output content passed by these events, you add code to the methods in the ContentHandlerImpl class. The ContentHandlerImpl class also implements the IVBSAXErrorHandler interface, which catches any error events thrown by the reader. At this time, the reader only invokes the fatalError method.

The simple filter application uses the sample XML file, books.xml.

See Also

Application Form | IMXWriter Interface | MXXMLWriter Coclass | ISAXContentHandler Interface | ISAXErrorHandler Interface | Sample XML File (books.xml)


Application Form

[This is preliminary documentation and subject to change.]

To get started, create a new project and then reference the Microsoft XML Parser (MSXML 4.0).

To create a new project

  • Open Microsoft® Visual Basic® 6.0, and in the New Project dialog box, double-click Standard EXE.

To create a reference to MSXML 4.0

  1. On the Project menu, click References.
  2. In the Available References list, select Microsoft XML,v4.0, and then click OK.

Add Controls to the Form

Now you must build the user interface for the simple filter application. Add the following controls to the form.

  • A text box, Text1, with the Multiline property set to True. This text box should be large enough to display the results of the parse process.
  • A text box, Text2, with "books.xml", the name of the file that the application parses and converts, specified as the Text property.
  • A text box, Text3. This text box is used to specify the element name that serves as the filter criteria.
  • A command button, Command1, with the caption Parse. This button starts the parse process.
  • A command button, Command2, with the caption Exit. This button closes the application.

The form should look like the following.

Add Code to the Form

The code for the form:

  • Creates instances of MXXMLWriter and SAXAttributes objects.
  • Creates an instance of the SAXXMLReader.
  • Creates an instance of the ContentHandlerImpl class implementing the IVBSAXContentHandler and IVBSAXErrorHandler interfaces.
  • Sets the errorHandler and the contentHandler properties for the SAXXMLReader to point to the ContentHandlerImpl class.
  • Sets the instance of MXXMLWriter to variables in the ContentHandlerImpl class that hold references to the IVBSAXContentHandler and IVBSAXErrorHandler interfaces. This enables the MXXMLWriter object to receive ContentHandler and ErrorHandler events.
  • Calls the SetFilterCriteria method in the ContentHandlerImpl class and sets the filter criteria.
  • Starts the parsing operation.

The following shows the complete code for the form.

'Create a writer and an attribute helper
Public oWriter As New MXXMLWriter
Public atrs As New SAXAttributes

Private Sub Command1_Click()
'create the reader
Dim rdr As New SAXXMLReader
'create the content handler
Dim cnth As New ContentHandlerImpl
'set the reader's content handler
Set rdr.contentHandler = cnth
'set the reader's error handler
Set rdr.errorHandler = cnth
'Set the writer for the content handler
Set cnth.oContentHandler = oWriter
'Set the error handler for the writer
Set cnth.oErrorHandler = oWriter

'configure output for the writer
oWriter.indent = True
oWriter.standalone = True
oWriter.output = ""
oWriter.omitXMLDeclaration = True

'set the filter criteria in the content handler
cnth.SetFilterCriteria (Text3.Text)

On Error GoTo HandleError

'parse the document
rdr.parseURL (Text2.Text)

Text1.Text = oWriter.output

Exit Sub

HandleError:
    If Not cnth.errorHappen Then
        Text1.Text = "**** Error **** " & Err.Number & " : " & Err.Description
    End If
End Sub
Private Sub Command2_Click()
    Unload Me
End Sub

See Also

How Filter Criteria is Set | IMXWriter Interface | MXXMLWriter Coclass | ISAXContentHandler Interface | ISAXErrorHandler Interface


How Filter Criteria is Set

One of the benefits of this sample application is that the code can return an element and its contents from any XML document. To achieve this, the Command1_Click() procedure contains a statement that calls the SetFilterCriteria method in the ContentHandlerImpl class and passes it the value of the Text3 text box, as shown in the following code.

   cnth.SetFilterCriteria (Text3.Text)

The following shows the SetFilterCriteria method in the ContentHandlerImpl class. The FilterCriteria variable is declared in the general section of the ContentHandlerImpl class.

   Public Sub SetFilterCriteria(elementname)
       FilterCriteria = elementname
   End Sub

The value of the FilterCriteria variable is then tested in the startElement method in the ContentHandlerImpl class to determine if the specified element is within scope. The code to test FilterCriteria in the ContentHandler methods, along with a full code listing for the ContentHandlerImpl class, is included in the following topic.

See Also

ContentHandlerImpl Class


ContentHandlerImpl Class

[This is preliminary documentation and subject to change.]

The ContentHandlerImpl class:

  • Implements the IVBSAXContentHandler and IVBSAXErrorHandler interfaces. The methods of these interfaces receive events thrown by the reader. You must add all methods for the implemented interfaces to the ContentHandlerImpl class.
  • Declares public variables for IVBSAXContentHandler and IVBSAXErrorHandler interfaces. The oContentHandler and oErrorHandler variables are set as properties of the ContentHandler object in the form and enable the writer to receive ContentHandler and ErrorHandler events.
  • Declares a FilterCriteria variable that holds the value of the element name that serves as the criteria for the filter. Declares a FilterTrue variable, a Boolean flag used to indicate whether the specified element is within scope. Declares an errorHappen variable, a Boolean flag that indicates whether the ErrorHandler has thrown a fatal error message. This prevents the ErrorHandler procedure in the form from overwriting the error message thrown by the error handler
  • Contains if statements and method calls that push content to the result fragment when the specified element is within scope.

To create the class

  1. On the Project menu, click Add Class Module.
  2. In the Add Class Module dialog box, double-click Class Module.
  3. On the View menu, select Properties Window.
  4. In the Properties Window, for the Name property, type ContentHandlerImpl.

To implement an interface

  1. In the code window, type "implements" and the name of the interface, for example:
    Implements IVBSAXContentHandler
Implements IVBSAXErrorHandler
  2. In the left-hand drop down in the code window, select the interface from the list.
  3. In the right-hand drop-down in the code window, you can implement the methods for the interface by selecting them from the list.
Note You must implement all methods for the implemented interfaces.

Complete Code for ContentHandlerImpl

Add the following code to the class.

Note If you already added the "Implements" statements, you can simply copy the following code over the top of them.

The essential methods used for the filter are discussed in the following topic.

Option Explicit
Implements IVBSAXContentHandler
Implements IVBSAXErrorHandler
'variable used for setting the writer to the content handler
Public oContentHandler As IVBSAXContentHandler
'variable used for setting the writer to the error handler
Public oErrorHandler As IVBSAXErrorHandler
'Indicates if the error handler has thrown a fatal error
Public errorHappen As Boolean
'Indicates if the element is in scope
Dim FilterTrue As Boolean
'Holds the element name
Dim FilterCriteria As String

Private Sub IVBSAXContentHandler_characters(strChars As String)
    If FilterTrue Then
           oContentHandler.characters strChars
    End If
End Sub

Private Property Set IVBSAXContentHandler_documentLocator(ByVal RHS As _
                                                    MSXML2.IVBSAXLocator)
    Initialize
End Property

Private Sub IVBSAXContentHandler_endDocument()

End Sub

Private Sub IVBSAXContentHandler_endElement(strNamespaceURI As String, _
                                            strLocalName As String, _
                                            strQName As String)
    If FilterTrue Then
         oContentHandler.endElement strNamespaceURI, strLocalName, _
                                    strQName
    End If
    If strLocalName = FilterCriteria Then
        FilterTrue = False
    End If
End Sub

Private Sub IVBSAXContentHandler_endPrefixMapping(strPrefix As String)

End Sub

Private Sub IVBSAXContentHandler_ignorableWhitespace(strChars As String)

End Sub

Private Sub IVBSAXContentHandler_processingInstruction(strTarget As _
                                                       String, _
                                                       strData As String)

End Sub

Private Sub IVBSAXContentHandler_skippedEntity(strName As String)

End Sub

Private Sub IVBSAXContentHandler_startDocument()

End Sub

Private Sub IVBSAXContentHandler_startElement(strNamespaceURI As String, _
                                              strLocalName As String, _
                                              strQName As String, _
                                              ByVal oAttributes As _
                                              MSXML2.IVBSAXAttributes)
    If strLocalName = FilterCriteria Then
        FilterTrue = True
    End If
    If FilterTrue Then
        oContentHandler.startElement strNamespaceURI, strLocalName, _
                                     strQName, oAttributes
    End If
End Sub

Private Sub IVBSAXContentHandler_startPrefixMapping(strPrefix As String,
                                                    strURI As String)

End Sub

Private Sub Initialize()
    errorHappen = False
    FilterTrue = False
End Sub

Private Sub IVBSAXErrorHandler_error(ByVal oLocator As _
                                     MSXML2.IVBSAXLocator, _
                                     strErrorMessage As String, _
                                     ByVal nErrorCode As Long)

End Sub

Private Sub IVBSAXErrorHandler_fatalError(ByVal oLocator As _
                                          MSXML2.IVBSAXLocator, _
                                          strErrorMessage As String, _
                                          ByVal nErrorCode As Long)
    Form1.Text1.Text = strErrorMessage & nErrorCode
    errorHappen = True
End Sub

Private Sub IVBSAXErrorHandler_ignorableWarning(ByVal oLocator As _
                                                MSXML2.IVBSAXLocator, _
                                                strErrorMessage As _
                                                String, _
                                                ByVal nErrorCode As Long)
End Sub

Public Sub SetFilterCriteria(elementname)
    FilterCriteria = elementname
End Sub

See Also

Essential Handler Methods | IMXWriter Interface | MXXMLWriter Coclass | ISAXContentHandler Interface | ISAXErrorHandler Interface


Essential Handler Methods

[This is preliminary documentation and subject to change.]

Although the Simple API for XML (SAX) can catch many events as it parses through a document, this application focuses on the most frequently used methods. In this example, the ContentHandlerImpl class implements all methods for IVBSAXContentHandler and IVBSAXErrorHandler interfaces, but code is added only to those methods that you want the application to be aware of, including documentLocator, startElement, endElement, characters, and endDocument for the ContentHandler, and fatalError for the ErrorHandler. As the reader passes through the document, it reports events in document order: documentLocator, followed by startDocument, startElement, characters, endElement, and endDocument.

set IVBSAXContentHandler_documentLocator method

The set IVBSAXContentHandler_documentLocator method is the first event thrown by the SAX reader when is passes through a document. This method receives a pointer to the IVBSAXLocator interface, which provides methods for returning the column number, line number, public ID, or system ID for a current document. Because this is the first method thrown, it is a good place to put initialization code.

In the following snippet, the Initialize procedure sets the TitleTrue flag, the flag that indicates if the element is within scope, to False. This procedure also sets the errorHappen flag to False. This flag is used to indicate that a fatal error has been thrown by the ErrorHandler and prevents the HandleError procedure in the form from overwriting the error message thrown by the ErrorHandler.

Private Property Set IVBSAXContentHandler_documentLocator(ByVal RHS As _
                                                    MSXML2.IVBSAXLocator)
    Initialize
End Property

Private Sub Initialize()
    errorHappen = False
    TitleTrue = False
End Sub

startElement Method

The startElement event is thrown by the reader each time it encounters the "<" character of a new element. The startElement method receives the namespace URI for the element, the local name, and the qualified name of the element. Attributes for the element are sent as a separate object containing the type, URI, local name, and value of each attribute. These values can be accessed from the attributes object within the startElement method.

In this method, the first if clause sets the FilterTrue flag if the element name passed by the startElement event matches the element name specified as the filter criteria. When FilterTrue is True, the second if clause invokes the startElement method from the oContentHandler object, which holds a reference pointing to oWriter, the MXXMLWriter object created in the form. This pushes the data passed by the startElement method to the oWriter object.

Private Sub IVBSAXContentHandler_startElement(strNamespaceURI As String, _
                                              strLocalName As String, _
                                              strQName As String, _
                                              ByVal oAttributes As _
                                              MSXML2.IVBSAXAttributes)
    If strLocalName = FilterCriteria Then
        FilterTrue = True
    End If
    If FilterTrue Then
        oContentHandler.startElement strNamespaceURI, strLocalName, _
                                     strQName, oAttributes
    End If
End Sub

characters Method

The characters method receives the character content between the opening and closing tags of an element. For this example, the characters method contains code that pushes character data to the writer only when the FilterTrue flag is set to True.

Private Sub IVBSAXContentHandler_characters(strChars As String)
    If FilterTrue Then
           oContentHandler.characters strChars
    End If
End Sub

endElement Method

SAX often throws events in pairs, modeling the structure of the XML document. For example, a startDocument event has a corresponding endDocument event and a startElement event has a corresponding endElement event. For the endElement method, the first if clause pushes the content received by the endElement method to the writer when the FilterTrue flag is True. The second if clause sets the FilterCriteria flag to False when the value passed by the endElement method matches the filter criteria. This indicates that the element is no longer in scope.

Private Sub IVBSAXContentHandler_endElement(strNamespaceURI As String, _
                                             strLocalName As String, _
                                             strQName As String)
    If FilterTrue Then
         oContentHandler.endElement strNamespaceURI, strLocalName, _
                                    strQName
    End If
    If strLocalName = FilterCriteria Then
        FilterTrue = False
    End If
End Sub

fatalError Method

Finally, code is added to the fatalError method to capture any errors thrown by the reader during parsing. If a fatal error is received, the error message is displayed in the Text1 box. The errorHappen flag is set to True, preventing the HandlerError routine in the form from overwriting the fatalError error message.

Private Sub IVBSAXErrorHandler_fatalError(ByVal oLocator As _
                                          MSXML2.IVBSAXLocator, _
                                          strErrorMessage As String,_
                                          ByVal nErrorCode As Long)
    Form1.Text1.Text = strErrorMessage & nErrorCode
    errorHappen = True
End Sub

See Also

Run the Application | IMXWriter Interface | MXXMLWriter Coclass | ISAXContentHandler Interface | ISAXErrorHandler Interface


Run the Application

[This is preliminary documentation and subject to change.]

The following instructions are based on the books.xml file, but you can use other XML documents as the file for this application.

To run the application

  1. Save the project and then copy books.xml to the folder where you saved the project.
  2. From the Visual Basic toolbar, click Start.
  3. In the Filename box, enter the path for books.xml file.
  4. In the Element name box, type the name of the element that serves as the filter criteria. For this example, type "title".
  5. On the form, click Parse.

The Text2 text box displays the following results.

<title>XML Developer's Guide</title>
<title>Midnight Rain</title>
<title>Maeve Ascendant</title>
<title>Oberon's Legacy</title>
<title>The Sundered Grail</title>
<title>Lover Birds</title>
<title>Splish Splash</title>
<title>Creepy Crawlies</title>
<title>Paradox Lost</title>
<title>Microsoft .NET: The Programming Bible</title>
<title>MSXML3: A Comprehensive Guide</title>
<title>Visual Studio 7: A Comprehensive Guide</title>

See Also

Sample XML File (books.xml)


Create a DOMDocument Object from SAX Events

[This is preliminary documentation and subject to change.]

With MSXML 4.0, you can generate a DOMDocument (or FreeThreadedDOMDocument) object from SAX events. This feature is useful when you want to create a small subset of XML from a large XML document and then use the DOM to process the results. For example, you may want to parse only small portions of a catalog, such as a book node, and store the results in a DOM object. You can then use the DOM to compare content, walk the DOM tree, and modify or update content. In addition, you may want to use SAX to search a large catalog file for a particular book. For performance gains, you can use SAX to locate a single item and then abort parsing after it is located. You can output the results of the search into a DOMDocument object and then apply DOM methods to the object.

This topic provides a simple example that demonstrates how to set a DOM object as the destination output for SAX events. It also provides implementation notes that describe some of the restrictions on the SAX to DOM implementation.

  • Overview of the SAX to DOM Example
  • Setting a DOMDocument Object as MXXMLWriter Output
  • SAX to DOM Implementation Notes


Overview of SAX to DOM Example

[This is preliminary documentation and subject to change.]

This simple SAX to DOM example uses Microsoft® Visual Basic® code that creates DOMDocument and MXXMLWriter objects, sets the MXXMLWriter object as the ContentHandler, and then sets the output property of the MXXMLWriter object as the DOMDocument object. ContentHandler method calls cause nodes to be built as the root document instance of the provided document. At the end of the procedure, DOM methods are used to return the author's name and display it in a message box.

To run the code sample

  1. Open Visual Basic 6.0, and in the New Project dialog box, double-click Standard EXE.
  2. In the Visual Basic 6.0 Window, from the Project menu, select References.
  3. Under Available References, select Microsoft XML, 4.0, and then click OK.
  4. In the Toolbox, click the Button control, and then add a button to the Form1 window.
  5. Add the following code to the Command1_Click procedure and then click Start on the toolbar.

The following shows the full sample code for the SAX to DOM example.

Private Sub Command1_Click()
    Dim xmlDoc As New MSXML2.DOMDocument
    Dim nodeList As IXMLDOMNodeList
    Dim wrt As New MXXMLWriter
    Dim cnth As IVBSAXContentHandler
    Dim atrs As New SAXAttributes

    Set cnth = wrt
    wrt.output = xmlDoc

    'sets standalone="yes" in the XML declaration
    'wrt.standalone = True
    'configures the writer to indent elements
    wrt.indent = True

    'starts the document by addding the XML declaration
    cnth.startDocument

    'adds the <catalog> element to the page
    cnth.startElement "", "", "catalog", atrs

    'adds the id attribute to the collection witht he "bk0101" value.
    atrs.addAttribute "", "", "id", "CDATA", "bk101"
    'creates the <book id="bk101"> tag
    cnth.startElement "", "", "book", atrs
    'clears the attribute collection
    atrs.Clear

    'creates the <author>Gambardella, Matthew</author> string
    cnth.startElement "", "", "author", atrs
    cnth.characters "Gambardella, Matthew"
    cnth.endElement "", "", "author"

    'creates the <title>XML Developer's Guide</title> string
    cnth.startElement "", "", "title", atrs
    cnth.characters "XML Developer's Guide"
    cnth.endElement "", "", "title"

    'creates the <description>An in-depth look at...</description> string
    cnth.startElement "", "", "description", atrs
    cnth.characters "An in-depth look at creating applications with XML"
    cnth.endElement "", "", "description"

    'adds closing tags for <book> and <catalog> elements
    cnth.endElement "", "", "book"
    cnth.endElement "", "", "catalog"

    'ends the document
    cnth.endDocument

    'displays the author's name in a message box
    Set objNodeList = xmlDoc.getElementsByTagName("author")
    MsgBox objNodeList.Item(0).Text
End Sub

See Also

Setting a DOMDocument Object as MXXMLWriter Output | MXXMLWriter Coclass | output Property | DOMDocument


Setting a DOMDocument Object as MXXMLWriter Output

[This is preliminary documentation and subject to change.]

The following code shows how to set the DOMDocument object as MXXMLWriter output and how to get the DOMDocument output using DOMDocument methods.

Setting Output

The following code shows how to set writer output as a DOMDocument object.

Private Sub Command1_Click()
    'create the DOMDocument object
    Dim xmlDoc As New MSXML2.DOMDocument
    'create an MXXMLWriter object
    Dim wrt As New MXXMLWriter
    'reference the ContentHandler interface
    Dim cnth As IVBSAXContentHandler

    'set the writer as the content handler
    Set cnth = wrt
    'set the writer output to the xmlDoc object
    wrt.output = xmlDoc

Getting Output

You can read the document at any time after the startDocument event is called. However, you cannot modify the document until after the endDocument event is called. The following code shows DOMDocument methods called on the xmlDoc object after the endElement method is called.

    cnth.endDocument

    'displays the author's name in a message box
    Set objNodeList = xmlDoc.getElementsByTagName("author")
    MsgBox objNodeList.Item(0).Text

See Also

SAX to DOM Implementation Notes | MXXMLWriter Coclass | output Property | DOMDocument


SAX to DOM Implementation Notes

[This is preliminary documentation and subject to change.]

You should be aware of the following considerations.

Reading and Modifying the DOMDocument Object

When a DOMDocument object is built from SAX events, the document is locked and cannot be modified until the endDocument method is called. The document can, however, be read anytime after startDocument method is called. The following provides an overview of how locking is applied as the document is built.

When the startDocument method is called, a write-lock is imposed on the document; existing data in the document is removed; and the lock is downgraded to a read-lock.

The read-lock is held on the document until one of the following conditions is met:

  • endDocument is called.
  • Any of the methods on the errorHandler interface are called.
  • The MXXMLWriter object is released and destructed.
  • There is an error (for example, a call to startElement fails).

Any attempt to modify the document while the read-lock is held will raise an error if the method is invoked from the current thread or block if invoked from a different thread.

Supported Methods

When a DOMDocument object is set as writer output, only the following methods are supported.

  • get/set output
  • get/set indent
  • flush()

Implemented Handlers

The following handler interfaces are implemented for SAX to DOM.

  • ISAXContentHandler/IVBSAXContentHandler
  • ISAXLexicalHandler/IVBSAXLexicalHandler
  • ISAXErrorHandler/IVBSAXErrorHandler

Allowed Sequence of Handler Callbacks

The following sequence of handler callbacks can be invoked.

startDocument
(comment | processingInstruction)*
(startElement ELEMENT_CONTENT endElement)
(comment | processingInstructions)*
endDocument

ELEMENT_CONTENT
Characters
| ignorableWhitespace
| startCDATA characters* endCDATA
| startElement ELEMENT_CONTENT* endElement
| skippedEntity
| startEntity ELEMENT_CONTENT* endEntity
| processingInstruction
| comment

When building a DOMDocument object, a startDocument event and its corresponding endDocument event must be called. If the callback sequence is not valid (for example, endElement is called without closing an open CDATA section), errorHandler aborts the parse and builds a parseError object from the provided information.

indent Property

When the indent property is set, characters() events are scanned to see if the event is purely white space. In this case, it is treated just like a white space event from the old parser. What this means is that when the only event to separate other (non-characters) events is a characters with only white space text, then there is no text node built for the white space, but the white space is remembered (as hints).

For example:

   startElement("","","a",attrs);
   characters("  ");
   endElement("","","a");

normally builds a DOM that looks like this:

   Element: nodeName="a"
       |
   TextNode "  "
which would be output like this:
   <a>  </a>

If the indent property is set, then Element node doesn't have a text child and the output looks like:

   <a>
   </a>
Note The indenting is due to special hints that are stored internally. They are not exposed in any manner, except as indenting when saving.

See Also

MXXMLWriter Coclass | output Property | DOMDocument


Throw SAX Events from a DOMDocument Object

[This is preliminary documentation and subject to change.]

With MSXML 4.0, you can use SAX and DOM interchangeably. For example, consider that a process hands your application a DOMDocument object. However, your application must scan the document, which is large, for a specific item or record. Rather than using the DOM to walk the tree, you can use the efficient, one-way processing offered by SAX to find the item and then abort parsing.

This topic provides an example that shows how you can parse a DOMDocument object with SAX events.

  • Overview of the DOM to SAX Example
  • Providing a DOMDocument Object as a Parse() Parameter


Overview of the DOM to SAX Example

[This is preliminary documentation and subject to change.]

The DOM to SAX example is Microsoft® Visual Basic® code that is run from a command button. This example creates DOMDocument and MXXMLWriter objects, sets the MXXMLWriter object as the ContentHandler, and then specifies the DOMDocument object as a parameter of the SAXXMLReader.parse() method. The results of the SAX events are written to the wrt.output property and displayed in a Visual Basic text box.

To run the code sample

  1. Copy books.xml to a folder on your hard drive.
  2. Open Visual Basic, and in the New Project dialog box, double-click Standard EXE.
  3. In the Visual Basic 6.0 Window, from the Project menu, select References.
  4. Under Available References, select Microsoft XML, 4.0 and then click OK.
  5. In the Toolbox, click the Button control, and then add a button to the Form1 window.
  6. Click the TextBox control and then add a TextBox to the Form1 window.
  7. Add the following code to the Command1_Click procedure.
  8. From the File menu, select Save Project As, and save the project to the folder where you copied books.xml.
  9. From the toolbar, click Start.
  10. To start parsing, click the Command1 button on the form.

The following shows the full sample code for the DOM to SAX example.

Private Sub Command1_Click()
    'create a DOMDocument object
    Dim xmlDoc As New DOMDocument
    'create the reader
    Dim rdr As New SAXXMLReader
    'create the writer
    Dim wrt As New MXXMLWriter

    On Error GoTo errorHandler

    xmlDoc.async = False
    xmlDoc.Load ("books.xml")

    wrt.byteOrderMark = True
    wrt.omitXMLDeclaration = False
    wrt.indent = True

    'set the writer to the content handler
    Set rdr.contentHandler = wrt
    Set rdr.dtdHandler = wrt
    Set rdr.errorHandler = wrt
    rdr.putProperty "http://xml.org/sax/properties/lexical-handler", _
                     wrt
    rdr.putProperty "http://xml.org/sax/properties/declaration-handler", _
                     wrt

    'parse the DOMDocument object
    rdr.parse xmlDoc

    'show the results in the text box
    Text1.Text = wrt.output

    Exit Sub

errorHandler:
    HandleErrors
End Sub

Private Function HandleErrors()
    MsgBox Err.Description
End Function

See Also

Providing a DOMDocument Object as a Parse() Parameter | ISAXXMLReader Interface | parse Method | DOMDocument | Sample XML File (books.xml)


Providing a DOMDocument Object as a Parse() Parameter

[This is preliminary documentation and subject to change.]

To parse a DOMDocument object with SAX, all you need to do is create a DOMDocument object, for example:

    Dim xmlDoc As New DOMDocument

Instead of a file or URL, specify the DOMDocument object as a parameter of the SAXXMLReader.parse() method, for example:

    rdr.parse xmlDoc

See Also

ISAXXMLReader Interface | parse Method | DOMDocument


Use MXXMLWriter

An MXXMLWriter object provides an efficient and flexible way to handle the output produced by the latest version of the Simple API for XML (SAX2) events. For example, an MXXMLWriter object:

  • Automatically handles the details of building an XML document or document fragment. When connected to SAXXMLReader, MXXMLWriter accumulates data passed by events thrown by the reader and stores the data in an output string. Also, MXXMLWriter can automatically handle the details of inserting special characters, such as the "<" character at the beginning of an element.
  • Enables you to format output by providing properties, such as omitXMLDeclaration, indent, and encoding, that apply to the document output.
  • Enables you to manually build an XML document by invoking the methods of the IVBSAXContentHandler, IVBSAXDTDHandler, IVBSAXDeclHandler, IVBSAXErrorHandler, and IVBSAXLexicalHandler interfaces.
  • Implements the IMXWriter interface, which is a complementary application programming interface (API) to the latest version of the Simple API for XML (SAX2) implementation of the Microsoft® XML Parser (MSXML).

MSXML provides two coclasses that implement IMXWriter: MXXMLWriter, which generates XML or DOM output and MXHTMLWriter, which generates HTML output.

To help you understand how you can incorporate MXXMLWriter into your applications, this section provides the following topics:

  • Overview of the Sample MXXMLWriter Application
  • Connecting an MXXMLWriter to a SAXXMLReader
  • Configuring MXXMLWriter Output
  • Manually Building an XML Document with MXXMLWriter

Although this tutorial covers the code included in the sample application, it is recommended that you download the sample MXXMLWriter application from the MSDN Code Center.

Other Resources Other Resources

Sample MXXMLWriter application


Overview of the Sample MXXMLWriter Application

The sample MXXMLWriter application, shown in the following illustration, consists of a single form with two buttons that enable you to perform two basic tasks:

  • The Try File button results in SAXXMLReader parsing the file given in the File name box, and passing that file's events to MXXMLWriter. The application then directs the output from MXXMLWriter to the large text box on the right. (The File name box defaults to the test.xml file provided with the sample application.)
  • The Try Demo button results in the application calling the required methods to manually build an XML file. The text box on the right shows the completed XML file; the text box on the left lists the events fired when each method is called.

Other Resources

Connecting an MXXMLWriter to a SAXXMLReader


Connecting an MXXMLWriter to a SAXXMLReader

In many of the applications that you create with the latest version of the Simple API for XML (SAX2), you use both SAXXMLReader, which reads an XML document and passes events, and MXXMLWriter, which catches the events and produces output based on the data passed by the events. Before MXXMLWriter can catch events, however, you must connect it to SAXXMLReader. MXXMLWriter, on its own, does not provide the handlers required to catch events thrown by SAXXMLReader.

To enable MXXMLWriter to handle events, you must assign the SAX2 handler interfaces to it. These handler interfaces include IVBSAXContentHandler, IVBSAXDTDHandler, IVBSAXDeclHandler, IVBSAXErrorHandler, and IVBSAXLexicalHandler. By assigning the SAX2 handler interfaces to your MXXMLWriter object, you make all the properties and methods of the interfaces available to it. In this way, your MXXMLWriter object can catch any of the events passed by SAXXMLReader. The following sections describe how to create SAXXMLReader and MXXMLReader objects and how to connect them.

Creating the SAXXMLReader and MXXMLWriter Objects

To create instances of SAXXMLReader and MXXMLWriter, use the following syntax. For the sample MXXMLWriter application, the creation of the SAXXMLReader and MXXMLWriter objects is in the Declarations section of the form.

Dim rdr As New SAXXMLReader
Dim wrt As New MXXMLWriter

Type casting MXXMLWriter to Handler Interfaces

SAX2 provides several handler interfaces that are designed to catch events passed by SAXXMLReader. You set these handler interfaces as properties of SAXXMLReader. To make these handler interfaces available to MXXMLWriter, you type cast MXXMLWriter to them.

For example, the sample MXXMLWriter application sets the contentHandler property of the rdr (SAXXMLReader) object to the wrt (MXXMLWriter) object, as shown in the following code. This registers the wrt object as the ContentHandler of the rdr object. This also sets the dtdHandler and errorHandler properties. You must set the declaration-handler and lexical-handler properties through the putProperty method.

Private Sub Form_Load()
    Set rdr.contentHandler = wrt
    Set rdr.dtdHandler = wrt
    Set rdr.errorHandler = wrt
    rdr.putProperty "http://xml.org/sax/properties/declaration-handler", _
      wrt
    rdr.putProperty "http://xml.org/sax/properties/lexical-handler", wrt
End Sub

Setting the Output Destination

In the sample MXXMLWriter application, clicking the Try File button clears both the text box and the output buffer (wrt.output). Then, the application calls the parse.URL method of SAXXMLReader and passes the name of the file in the TextFileName text box (as shown in bold in the following code sample). At this point, SAXXMLReader fires a series of events to pass the data in the XML document to the wrt object, which stores this data in the output buffer. By default, the output is a string value that, in this case, is set to the textResult.text box (as shown in bold in the following code sample). The output destination can also be set as an IStream.

Private Sub CommandTryFile_Click()
    ' Set parameters, clean the scene
    TextSource.Text = ""
    wrt.output = ""
    wrt.omitXMLDeclaration = True
    On Error GoTo uhoh
    rdr.parseURL TextFileName.Text
    TextResult.Text = wrt.output
    Exit Sub
uhoh:
    TextResult.Text = "Error: " & Err.LastDllError & " -- " & _
      Err.Description & vbCrLf & "Check if file exists in the _
      correct place"
End Sub

See Also

Configuring MXXMLWriter Output | ISAXXMLReader Interface | IMXWriter Interface | ISAXContentHandler Interface | ISAXDeclHandler Interface | ISAXDTDHandler Interface | ISAXErrorHandler Interface | ISAXLexicalHandler Interface | output Property


Configuring MXXMLWriter Output

MXXMLWriter provides properties that you can set to control its output, including encoding, indent, omitXMLDeclaration, and output.

For example, the sample MXXMLWriter application creates a document fragment from an XML document. It does this by the way it sets the omitXMLDeclaration property. When you set this property to True (as shown in bold in the following code sample), MXXMLWriter strips the XML declaration from an XML document before placing the document in the internal output buffer.

Private Sub CommandTryFile_Click()
    ' Set parameters, clean the scene
    TextSource.Text = ""
    wrt.output = ""
    wrt.omitXMLDeclaration = True
    On Error GoTo uhoh
    rdr.parseURL TextFileName.Text

    TextResult.Text = wrt.output
    Exit Sub

The following table shows how setting the omitXMLDeclaration property to True removes the XML declaration from a document.

wrt.omitXMLDeclaration = False | wrt.omitXMLDeclaration = True
<?xml version="1.0" encoding="UTF-16" standalone="no"?> <root aaa="microsoft.com"> <PARTS>… | <root aaa="microsoft.com"> <PARTS>…

There are other ways that you can configure your MXXMLWriter object to control its output. For more information about the properties you can set for MXXMLWriter, see the IMXWriter Interface.

See Also

Manually Building an XML Document with MXXMLWriter


Manually Building an XML Document with MXXMLWriter

Using MXXMLWriter, you can build an XML document by manually calling methods of the Simple API for XML (SAX2) handlers. This section demonstrates how you can use type casting to get the interfaces that MXXMLWriter implements and how you can manually make calls to the methods of these interfaces to build an XML document. In this case, the application emulates SAXXMLReader by manually invoking the methods of the various handler interfaces, including IVBSAXContentHandler, IVBSAXDTDHandler, IVBSAXDeclHandler, IVBSAXErrorHandler, and IVBSAXLexicalHandler. In this portion of the sample MXXMLWriter application, SAXXMLReader is not used.

On its own, the IMXXMLWriter interface does not provide the handler methods required to manually construct an XML document. However, you can type cast MXXMLWriter to the required handler interfaces, which provides all the methods and properties to MXXMLWriter.

As you can see in the following sample application code, clicking the Try Demo button results in the application declaring the handler interface variables and then setting these handlers to the wrt object. This makes it possible for the wrt object to use any of the methods or properties of the declared handler interfaces.

Private Sub CommandTryDemo_Click()
    ' We need these variables for typecasting the writer
    Dim cnth As IVBSAXContentHandler
    Dim dtdh As IVBSAXDTDHandler
    Dim lexh As IVBSAXLexicalHandler
    Dim dech As IVBSAXDeclHandler
    Dim errh As IVBSAXErrorHandler

    ' This is just a helper
    Dim atrs As New SAXAttributes

    ' Set them all to writer, writer implements all these interfaces
    Set cnth = wrt
    Set dtdh = wrt
    Set lexh = wrt
    Set dech = wrt
    Set errh = wrt

    ' Set parameters, clean the scene
    TextSource.Text = ""

In the sample MXXMLWriter application, the remainder of the CommandTryDemo_Click() subroutine constructs the document by calling various handler methods. For example, the following statement invokes the startDocument method of the IVBSAXContentHandler interface:

    cnth.startDocument

In a similar way, the following statement invokes the startDTD method of the IVBSAXLexicalHandler interface and passes the parameters to the wrt object:

    lexh.startDTD "MyDTD", "", "http://eureka.sample/mydtd.dtd"

Coupled with each call to a handler method, there is a call to the log subroutine, as follows:

    log "Content->startDocument"

The log subroutine, as shown in the following code, creates an entry in the left-hand text box for each method called.

Private Sub log(msg As String)
    TextSource.Text = TextSource.Text & vbCrLf & msg
End Sub

At the end of the CommandTryDemo_Click() subroutine, the application sets the textResults.text box to the output of the writer (as in the following code). Unless you flush the output buffer, it continues to aggregate data passed to it by the handlers.

TextResult.Text = wrt.output

Complete Code for the CommandTryDemo_Click() Subroutine

Private Sub CommandTryDemo_Click()
    'We need these variables for typecasting the writer
    Dim cnth As IVBSAXContentHandler
    Dim dtdh As IVBSAXDTDHandler
    Dim lexh As IVBSAXLexicalHandler
    Dim dech As IVBSAXDeclHandler
    Dim errh As IVBSAXErrorHandler

    'This is just a helper
    Dim atrs As New SAXAttributes

    'Set handler variables to the writer so it implements the interfaces
    Set cnth = wrt
    Set dtdh = wrt
    Set lexh = wrt
    Set dech = wrt
    Set errh = wrt

    ' Set parameters, clean the scene
    TextSource.Text = ""

    ' Manually call necessary events to generate the XML file
    log "Content->startDocument"
    cnth.startDocument
    log "Lexical->startDTD"
    lexh.startDTD "MyDTD", "", "http://eureka.sample/mydtd.dtd"
        log "Decl->elementDecl"
        dech.elementDecl "book", "title | descr"
        log "Decl->attributeDecl"
        dech.attributeDecl "book", "author", "CDATA", "#IMPLIED", ""
        log "Decl->attributeDecl"
        dech.attributeDecl "book", "ISBN", "CDATA", "#REQUIRED", _
          "000000000"
        log "Decl->attributeDecl"
        dech.attributeDecl "book", "cover", "(hard|soft)", "", "soft"
        log "Decl-elementDecl"
        dech.elementDecl "title", "(#PCDATA)"
        log "Decl-elementDecl"
        dech.elementDecl "descr", "(#PCDATA)"
    log "Lexical->endDTD"
    lexh.endDTD
    log "Content->startElement"
    atrs.addAttribute "", "", "cover", "", "hard"
    cnth.startElement "", "", "book", atrs
        log "Content->startElement"
        atrs.Clear
        cnth.startElement "", "", "title", atrs
        log "Content->characters"
        cnth.characters "On the Circular Problem of Quadratic Equations"
        log "Content->endElement"
        cnth.endElement "", "", "title"
    log "Content->endElement"
    cnth.endElement "", "", "book"

    TextResult.Text = wrt.output
End Sub

See Also

ISAXXMLReader Interface | IMXWriter Interface | ISAXContentHandler Interface | ISAXDeclHandler Interface | ISAXDTDHandler Interface | ISAXErrorHandler Interface | ISAXLexicalHandler Interface


SAX2 Reference

The Simple API for XML (SAX) was originally defined for the Java programming language using Java interface definitions. Because the Java language interfaces are not language-neutral, tool vendors must decide how the SAX interfaces will map to a specific language. In the future, however, standard language bindings will emerge.

Microsoft added support for SAX in MSXML 3.0. There is support for C++ and Microsoft Visual Basic®. Each of these language bindings requires a different set of interfaces that reflect the individual language and type restrictions.

The names of the MSXML interfaces are the same as those in the Java language, but are prefixed with ISAX for C++ and IVBSAX for Visual Basic (ISAXContentHandler and IVBSAXContentHandler, for example).

This section contains the following topics.

  • IMXAttributes Interface
  • IMXReaderControl Interface
  • IMXWriter Interface
  • ISAXAttributes Interface
  • ISAXContentHandler Interface
  • ISAXDeclHandler Interface
  • ISAXDTDHandler Interface
  • ISAXEntityResolver Interface
  • ISAXErrorHandler Interface
  • ISAXLexicalHandler Interface
  • ISAXLocator Interface
  • ISAXXMLFilter Interface
  • ISAXXMLReader Interface
  • SAX2 C++ Common Notices
  • SAX2 Visual Basic Common Notices


IMXAttributes Interface

The IMXAttributes interface complements the implementation of the ISAXAttributes interface, allowing you to create and edit, and not just query, attribute collections. Implemented coclasses (for ISAXAttributes and IMXAttributes) are SAXAttributes (version-independent) and SAXAttributes40 (the version-dependent class for the Microsoft® XML Parser 4.0).

Note Coclasses define a class to the Component Object Model (COM). The coclass definitions include a list of interfaces supported by COM objects created from this class.

This implementation of the IMXAttributes interface returns what is put inside. Because the ISAXAttributes implementation cannot be sure which implementation is provided, it cannot be sure of the validity of attributes. The requirements of different applications may be different. For this reason, the implementation of the coclass does not enforce any assumption about input information, accepting it whenever possible.

The two uses for this interface are:

  • to take a persistent snapshot of an attribute.
  • to construct or modify an attribute's object in a Simple API for XML (SAX2) driver or filter.

Methods

addAttribute | Adds an attribute to the end of the attribute collection.
addAttributeFromIndex | Adds an attribute, whose value is equal to the indexed attribute in the input attributes object, to the end of the list.
clear | Clears the attribute list for reuse.
removeAttribute | Removes an attribute from the list.
setAttribute | Sets an attribute in the list.
setAttributes | Copies all existing attributes of a collection to a specified object.
setLocalName | Sets the local name of a specific attribute.
setQName | Sets the qualified name (QName) of a specific attribute.
setType | Sets the type of a specific attribute.
setURI | Sets the namespace URI of a specific attribute.
setValue | Sets the value of a specific attribute.

Requirements

[Visual Basic, C/C++]

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and LIB files: msxml2.h, msxml2.lib

Version-Independent ProgID: msxml2.SAXAttributes

Version-Independent CLSID: 4dd441ad-526d-4a77-9f1b-9841ed802fb0

Version 3.0 Dependent ProgID: msxml2.SAXAttributes30

Version 3.0 Dependent CLSID: 3e784a01-f3ae-4dc0-9354-9526b9370eba

Version 4.0 Dependent ProgID: msxml2.SAXAttributes40

Version 4.0 Dependent CLSID: 88d969ca-f192-11d4-a65f-0040963251e5


addAttribute Method

Adds an attribute to the end of the attribute collection.

[Visual Basic]

Implementation Syntax

Sub addAttribute(ByVal strURI As String, _
                 ByVal strLocalName As String, _
                 ByVal strQName As String, _
                 ByVal strType As String, _
                 ByVal strValue As String)

Usage Syntax

oIMXAttributes.addAttribute(strURI, _
                            strLocalName, _
                            strQName, _
                            strType, _
                            strValue)

Parameters

strURI
The namespace Uniform Resource Identifier (URI) or, if the namespace has no URI, an empty string.
strLocalName
The local name of the attribute.
strQName
The XML 1.0 qualified name or, if the qualified name is not available, an empty string.
strType
A string representing the attribute type.
strValue
A string representing the attribute default value specified by "#IMPLIED", "#REQUIRED", or "#FIXED", or Null if none applies. This value string is represented by the attribute's default value, or empty if there is none.
[C/C++]

Adds an attribute to the end of the attribute collection.

Syntax

HRESULT addAttribute(
    [in] BSTR strURI,
    [in] BSTR strLocalName,
    [in] BSTR strQName,
    [in] BSTR strType,
    [in] BSTR strValue);

Parameters

strURI
The namespace Uniform Resource Identifier (URI) or, if the namespace has no URI, an empty string.
strLocalName
The local name of the attribute.
strQName
The XML 1.0 qualified name or, if the qualified name is not available, an empty string.
strType
A string representing the attribute type.
strValue
A string representing the attribute's default value specified by "#IMPLIED", "#REQUIRED", or "#FIXED", or Null if none applies. This value string is represented by the attribute's default value, or empty if there is none.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

To maximize efficiency, the addAttribute method does not check if the attribute is in the list. Therefore, the user application should check for the existence of an attribute before adding it to the bottom of the attribute list.

See Also

Applies to: IMXAttributes Interface


addAttributeFromIndex Method

Adds an attribute, whose value is equal to the indexed attribute in the input attributes object, to the end of the list.

[Visual Basic]

Implementation Syntax

Sub addAttributeFromIndex(ByVal varAtts, ByVal nIndex As Long)

Usage Syntax

oIMXAttributes.addAttributeFromIndex(varAtts, nIndex)
[C/C++]

Syntax

HRESULT addAttributeFromIndex(
    [in] VARIANT varAtts,
    [in] int nIndex);

Return Values

S_OK
The value returned if no errors are reported.
E_FAIL
The value returned if index is out of range.

Parameters

varAtts
The variant type.
nIndex
The attribute's index value.

See Also

Applies to: IMXAttributes Interface


clear Method

Clears the attribute list for reuse.

[Visual Basic]

Implementation Syntax

Sub clear()

Usage Syntax

oIMXAttributes.clear
[C/C++]

Syntax

HRESULT clear();

Return Values

S_OK
The value returned if no errors are reported.
E_FAIL
There is only one specific fatal error for this IMXAttributes implementation: setAttribute with incorrect index (E_INVALIDARG). It may return a generic failure code, such as out-of-memory.

Remarks

This call does not free memory. The current arrays are kept for reuse.

See Also

Applies to: IMXAttributes Interface


removeAttribute Method

Removes an attribute from the list.

[Visual Basic]

Implementation Syntax

Sub removeAttribute(nIndex As Long)

Usage Syntax

oIMXAttributes.removeAttribute(nIndex)
[C/C++]

Syntax

HRESULT removeAttribute(
    [in] int nIndex);

Return Values

S_OK
The value returned if no errors are reported.
E_FAIL
There is only one specific fatal error for this IMXAttributes implementation: incorrect index (E_INVALIDARG). It may return a generic failure code, such as out-of-memory.

Parameters

nIndex
The attribute's index value (zero-based).

See Also

Applies to: IMXAttributes Interface


setAttribute Method

Sets an attribute in the list.

[Visual Basic]

Implementation Syntax

Sub setAttribute(ByVal nIndex As Long, _
                 ByVal strURI As String, _
                 ByVal strLocalName As String, _
                 ByVal strQName As String, _
                 ByVal strType As String, _
                 ByVal strValue As String)

Usage Syntax

oIMXAttributes.setAttribute(nIndex, _
                            strURI, _
                            strLocalName, _
                            strQName, _
                            strType, _
                            strValue)

Parameters

nIndex
The attribute's index value (zero-based).
strURI
The namespace Uniform Resource Identifier (URI) or, if the namespace has no URI, an empty string.
strLocalName
The local name or, if namespace processing is not being performed, an empty string.
strQName
The XML 1.0 qualified name or, if the qualified name is not available, an empty string.
strType
A string representing the attribute type.
strValue
The attribute value.
[C/C++]

Syntax

HRESULT setAttribute(
    [in] int nIndex,
    [in] BSTR strURI,
    [in] BSTR strLocalName,
    [in] BSTR strQName,
    [in] BSTR strType,
    [in] BSTR strValue);

Parameters

nIndex
The attribute's index value (zero-based).
strURI
The namespace Uniform Resource Identifier (URI) or, if the namespace has no URI, an empty string.
strLocalName
The local name or, if namespace processing is not being performed, an empty string.
strQName
The XML 1.0 qualified name or, if the qualified name is not available, an empty string.
strType
A string representing the attribute type.
strValue
The attribute value.

Return Values

S_OK
The value returned if no errors are reported.
E_FAIL
There is only one specific fatal error for this IMXAttributes implementation: incorrect index (E_INVALIDARG). It may return a generic failure code, such as out-of-memory.

See Also

Applies to: IMXAttributes Interface


setAttributes Method

Copies all existing attributes of a collection to a specified object.

[Visual Basic]

Implementation Syntax

Sub setAttributes(varAtts)

Usage Syntax

oIMXAttributes.setAttribute(varAtts)
[C/C++]

Syntax

HRESULT setAttributes(IMXAttributes * varAtts);

Return Values

S_OK
The value returned if no errors are reported.

Parameters

varAtts
The variant attribute collection.

Remarks

It may be more efficient to reuse an existing object rather than allocating a new one.

See Also

Applies to: IMXAttributes Interface


setLocalName Method

Sets the local name of a specific attribute.

[Visual Basic]

Implementation Syntax

Sub setLocalName(ByVal nIndex As Long, ByVal strLocalName As String)

Usage Syntax

oIMXAttributes.setLocalName(nIndex, strLocalName)
[C/C++]

Syntax

HRESULT setLocalName(
    [in] int nIndex,
    [in] BSTR strLocalName);

Return Values

S_OK
The value returned if no errors are reported.
E_FAIL
There is only one specific fatal error for this IMXAttributes implementation: incorrect index (E_INVALIDARG). It may return a generic failure code, such as out-of-memory.

Parameters

nIndex
The attribute's index value (zero-based).
strLocalName
The local name of the attribute or, if there is none, an empty string.

See Also

Applies to: IMXAttributes Interface


setQName Method

Sets the qualified name (QName) of a specific attribute.

[Visual Basic]

Implementation Syntax

Sub setQName(ByVal nIndex As Long, ByVal strQName As String)

Usage Syntax

oIMXAttributes.setQName(nIndex, strQName)
[C/C++]

Syntax

HRESULT setQName(
    [in] int nIndex,
    [in] BSTR strQName);

Return Values

S_OK
The value returned if no errors are reported.
E_FAIL
There is only one specific fatal error for this IMXAttributes implementation: incorrect index (E_INVALIDARG). It may return a generic failure code, such as out-of-memory.

Parameters

nIndex
The attribute's index value.
strQName
The XML 1.0 qualified name or, if the qualified name is not available, an empty string.

See Also

Applies to: IMXAttributes Interface


setType Method

Sets the type of a specific attribute. This is a user-created type if it is has not been declared in the document type definition (DTD).

[Visual Basic]

Implementation Syntax

Sub setType(ByVal nIndex As Long, ByVal strType As String)

Usage Syntax

oIMXAttributes.setType(nIndex, strType)
[C/C++]

Syntax

HRESULT setType(
    [in] int nIndex,
    [in] BSTR strType);

Return Values

S_OK
The value returned if no errors are reported.
E_FAIL
There is only one specific fatal error for this IMXAttributes implementation: incorrect index (E_INVALIDARG). It may return a generic failure code, such as out-of-memory.

Parameters

nIndex
The attribute's index value (zero-based), used to specify the attribute.
strType
A string representing the attribute type.

See Also

Applies to: IMXAttributes Interface


setURI Method

Sets the namespace URI of a specific attribute.

[Visual Basic]

Implementation Syntax

Sub setURI(ByVal nIndex As Long, ByVal strURI As String)

Usage Syntax

oIMXAttributes.setURI(nIndex, strURI)
[C/C++]

Syntax

HRESULT setURI(
    [in] int nIndex,
    [in] BSTR strURI);

Return Values

S_OK
The value returned if no errors are reported.
E_FAIL
There is only one specific fatal error for this IMXAttributes implementation: incorrect index (E_INVALIDARG). It may return a generic failure code, such as out-of-memory.

Parameters

nIndex
The attribute's index value (zero-based), used to specify the attribute.
strURI
The namespace URI or, if the namespace has no URI. an empty string.

See Also

Applies to: IMXAttributes Interface


setValue Method

Sets the value of a specific attribute.

[Visual Basic]

Implementation Syntax

Sub setValue(ByVal nIndex As Long, ByVal strValue As String)

Usage Syntax

oIMXAttributes.setValue(nIndex, strValue)
[C/C++]

Syntax

HRESULT setValue(
    [in] int nIndex,
    [in] BSTR strValue);

Return Values

S_OK
The value returned if no errors are reported.
E_FAIL
There is only one specific fatal error for this IMXAttributes implementation: incorrect index (E_INVALIDARG). It may return a generic failure code, such as out-of-memory.

Parameters

nIndex
The attribute's index value.
strValue
A string representing the attribute default value specified by "#IMPLIED", "#REQUIRED", or "#FIXED", or Null if none applies. This value string is represented by the attribute's default value, or Null if there is none.

See Also

Applies to: IMXAttributes Interface


IMXReaderControl Interface

IMXReaderControl provides limited control on reader behavior. Namely, it allows a Simple API for XML (SAX2) application to abort, suspend, or resume parsing.

Note The IMXReaderControl is nonstandard. If you use this feature, you may not be able to migrate your program logic to other SAX implementations. IMXReaderControl is targeted to applications that require a low-level parser API.

Methods

abort | Stops the parsing operation.
resume | Resumes parsing after the reader has been suspended with the suspend method.
suspend | Suspends parsing and returns control to the application.

Requirements

[Visual Basic, C/C++]

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and LIB files: msxml2.h, msxml2.lib


abort Method

Stops the parsing operation.

[Visual Basic]

Usage Syntax

oSAXXMLReader.abort

The following table shows the behavior for the abort method based on the state of the reader.

State | Behavior
Ready | Returns a trappable error. After abort executes, the reader is again ready to parse.
Parsing | After abort executes, the reader is again ready to parse.
Suspended | After abort executes, the reader is again ready to parse.

[C/C++]

Syntax

HRESULT abort( );

Return Values

The following table shows the return codes for the abort method based on the state of the reader.

State | Return Code
Ready | E_FAIL. (After abort executes, the reader is again ready to parse.)
Parsing | S_OK. (After abort executes, the reader is again ready to parse.)
Suspended | S_OK. (After abort executes, the reader is again ready to parse.)

Remarks

You should use abort from within a handler call. After abort executes, parsing stops, but processing of the handler method continues.

[C/C++]

As an alternative to the abort method, you can return E_FAIL.

See Also

resume Method | suspend Method

Applies to: IMXReaderControl Interface


resume Method

Resumes parsing after the reader has been suspended with the suspend method.

[Visual Basic]

Usage Syntax

oSAXXMLReader.resume

The following table shows the behavior for the resume method based on the state of the reader.

State | Behavior
Ready | Returns a trappable error. (The reader remains in the ready state.)
Parsing | Returns a trappable error. (The reader continues parsing.)
Suspended | The return code is defined by the parse or resume methods or handler. (After resume executes, the reader starts parsing.)

[C/C++]

Syntax

HRESULT resume( );

Return Values

The following table shows the return codes for the resume method based on the state of the reader.

State | Return Code
Ready | E_FAIL (Resume executes, but the reader remains in the ready state.)
Parsing | E_FAIL (Resume executes, but the reader continues to parse.)
Suspended | The return code is defined by the parse or resume methods or handler. After resume executes, the reader starts parsing.

Remarks

The resume method must be called from outside a handler call.

See Also

abort Method | suspend Method

Applies to: IMXReaderControl Interface


suspend Method

Suspends parsing and returns control to the application.

[Visual Basic]

Usage Syntax

oSAXXMLReader.suspend

The following table shows behavior for the suspend method based on the state of the reader.

State | Behavior
Ready | Raises a trappable error. (If suspend is called when the reader is in the ready state, the reader remains in the ready state.)
Parsing | After the suspend executes, the reader is suspended.
Suspended | Raises a trappable error. (If suspend is called when the reader is in the suspended state, the reader remains in the suspended state.)

[C/C++]

Suspends parsing and returns control to the application with an E_PENDING HRESULT.

Syntax

HRESULT suspend( );

Return Values

The following table shows the return codes for the suspend method based on the state of the reader.

State | Return Code
Ready | E_FAIL (If suspend is called when the reader is not parsing, the reader remains in the ready state.)
Parsing | S_OK (Suspends the reader.)
Suspended | E_FAIL. (If suspend is called while the reader is suspended, the reader remains suspended.)

Remarks

You can only suspend the reader during parsing. The suspend method must be called from within a handler call. Parsing can be restarted later with the resume method.

See Also

abort Method | resume Method

Applies to: IMXReaderControl Interface


IMXWriter Interface

[This is preliminary documentation and subject to change.]

The IMXWriter interface is a complementary application programming interface (API) to the latest version of the Simple API for XML (SAX2) implementation of the Microsoft® XML Parser (MSXML). MSXML provides two coclasses that implement IMXWriter.

Coclass | Description
MXXMLWriter | Generates XML or DOM output.
MXHTMLWriter | Generates HTML output.

The following can be set as output for IMXWriter:

  • Any implementation of the IStream interface. (The resulting document will be written into the provided IStream.)
  • A string.
  • A DOMDocument object.

    For more information about setting the output property to a DOMDocument object, see Create a DOMDocument Object from SAX Events.

IMXWriter also enables you to:

  • control the output of a document by setting properties, such as omitXMLDeclaration, indent, and encoding.
  • generate XML or HTML content by invoking methods of the ISAXContentHandler, ISAXDTDHandler, ISAXDeclHandler, and ISAXLexicalHandler interfaces.
    Important The IMXWriter interface implements the ISAXContentHandler, ISAXDTDHandler, ISAXErrorHandler, ISAXDeclHandler, and ISAXLexicalHandler interfaces. However, to enable the writer to catch handler events passed by SAXXMLReader, you must set the writer as the ContentHandler, and, optionally, as any of the other handlers. For more information about how to set a writer as a handler, see Use MXXMLWriter.

Ideally, a writer connected to SAXXMLReader produces the same document as provided on the input. However, the writer may miss content deemed ignorable by XML 1.0 specifications or may output in a different encoding. For example, national encoding can be replaced with Unicode Transformation Format (UTF-8 or UTF-16). Replacing the encoding becomes useful if you use a custom SAXXMLFilter between SAXXMLReader and the writer.

IMXWriter uses the generous input approach, which means it outputs what is entered. It is the responsibility of the application to ensure that SAX events and parameters match those of a well-formed or valid XML document.

Properties

byteOrderMark | Determines whether to write the Byte Order Mark (BOM). The byteOrderMark property has no effect for BSTR or DOM output.
disableOutputEscaping | Matches the disable-output-escaping attribute of the <xsl:text> and <xsl:value-of> elements. When set to True, special symbols such as "&" are passed through literally.
encoding | Sets and gets encoding for the output.
indent | Sets whether to indent output.
omitXMLDeclaration | Forces the IMXWriter to skip the XML declaration. Useful for creating document fragments.
output | Sets the destination and the type of output for IMXWriter.
standalone | Sets the value of the standalone attribute in the XML declaration to "yes" or "no".
version | Specifies the version to include in XML declarations.

Methods

In addition to the preceding properties, the following method also applies to the IMXWriter interface.

flush Flushes the object's internal buffer to its destination IStream/string. The flush method has no effect for DOM output.

Requirements

[Visual Basic, C/C++]

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and LIB files: msxml2.h, msxml2.lib

Version-Independent ProgID: msxml2.MXXMLWriter

Version-Independent CLSID: fc220ad8-a72a-4ee8-926e-0b7ad152a020

Version 3.0 Dependent ProgID: msxml2.MXXMLWriter30

Version 3.0 Dependent CLSID: 3d813dfe-6c91-4a4e-8f41-04346a841d9c

Version 4.0 Dependent ProgID: msxml2.MXXMLWriter40

Version 4.0 Dependent CLSID: 88d969c8-f192-11d4-a65f-0040963251e5

Version-Independent ProgID: msxml2.MXHTMLWriter

Version-Independent CLSID: a4c23ec3-6b70-4466-9127-550077239978

Version 3.0 Dependent ProgID: msxml2.MXHTMLWriter30

Version 3.0 Dependent CLSID: 853d1540-c1a7-4aa9-a226-4d3bd301146d

Version 4.0 Dependent ProgID: msxml2.MXHTMLWriter40

Version 4.0 Dependent CLSID: 88d969c9-f192-11d4-a65f-0040963251e5


flush Method

[This is preliminary documentation and subject to change.]

Flushes the object's internal buffer to its destination IStream/string. This flushing occurs when one of the following conditions is met:

  • The output property is set to a destination.
  • The endDocument() event is called.
  • The flush() method is called.
[Visual Basic]

Implementation Syntax

Sub flush()

Usage Syntax

oMXXMLWriter.flush
[C/C++]

Syntax

HRESULT flush ( );

Return Values

S_OK
The value returned if no errors are reported.

Remarks

The flush method has no effect for DOM output. Avoid handling the underlying IStream object during output (for example, direct writing). Keep in mind that a correspondence between Simple API for XML (SAX2) events and output text is not generally specified, although an implementation can provide it. Therefore, when using the flush method, the exact position within the generated document is not generally known. If the flush method interrupts writer output, all output that has been processed is put into the underlying IStream/ISequentialStream object.

See Also

output Property | MXHTMLWriter Coclass | MXXMLWriter Coclass

Applies to: IMXWriter Interface


byteOrderMark Property

[This is preliminary documentation and subject to change.]

Determines whether to write the Byte Order Mark (BOM) to output.

When set to True, IMXWriter follows XML 1.0 specifications and outputs BOM for appropriate encoding. When set to False, IMXWriter is prohibited from putting BOM into the resulting XML document.

[Visual Basic]

Implementation Syntax

Property Let IMXWriter_byteOrderMark(ByVal RHS As Boolean)
Property Get IMXWriter_byteOrderMark() As Boolean

Usage Syntax

oMXXMLWriter.byteOrderMark = boolValue
boolValue = oMXXMLWriter.byteOrderMark

Remarks

Boolean. Read/write. The byteOrderMark property has no effect for BSTR or DOM output.

[C/C++]

Syntax

[proput]
HRESULT byteOrderMark (
  [in] VARIANT_BOOL fWriteByteOrderMark);

[propget]
HRESULT byteOrderMark (
  [out, retval] VARIANT_BOOL * fWriteByteOrderMark);

Parameters

fWriteByteOrderMark
A Boolean expression (True/False) specifying whether the feature is on or off.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

The default of this property depends on the implementation. IMXWriter never outputs BOM if the output is set to a string. The byteOrderMark property has no effect for BSTR or DOM output.

Value | Description
True | IMXWriter follows XML 1.0 specifications and outputs BOM for encoding.
False | IMXWriter is prohibited from putting BOM into the resulting XML document.

See Also

MXHTMLWriter Coclass | MXXMLWriter Coclass

Applies to: IMXWriter Interface


disableOutputEscaping Property

[This is preliminary documentation and subject to change.]

Matches the disable-output-escaping attribute of the <xsl:text> and <xsl:value-of> elements. For example, normally escaped built-in entities such as "&amp;" for "&" are passed through literally.

[Visual Basic]

Implementation Syntax

Property Let IMXWriter_disableOutputEscaping(ByVal RHS As Boolean)
Property Get IMXWriter_disableOutputEscaping() As Boolean

Usage Syntax

oMXXMLWriter.disableOutputEscaping = boolValue
boolValue = oMXXMLWriter.disableOutputEscaping

Remarks

Boolean. Read/write. The disableOutputEscaping property has no effect for DOM output.

Example

In some cases, you may want to merge an XML document fragment with an XML document. If the document fragment has not been parsed, the "&" character will be escaped as "&amp;" in the document fragment. However, if you merge the document fragment into an XML document, the "&amp;" will be escaped again when it is parsed. To avoid the situation where an already escaped character is escaped again, you can set the disableOutputEscaping property to True. The following code sample manually generates an XML document to demonstrate how this works. For the first element created, disableOutputEscaping is left as False, resulting in a double-escaped character. However, in the second element generated, disableOutputEscaping is set to True, enabling the "GG&amp;G" value to be passed through as intended.

Dim wrt As New MXXMLWriter
Dim cnth As IVBSAXContentHandler
Dim atrs As New SAXAttributes
Set cnth = wrt

starts the document by addding the XML declaration
cnth.startDocument

'this section escapes the character.
cnth.startElement "", "", "company", atrs
cnth.characters "GG&amp;G"
cnth.endElement "", "", "company"

'this section passes the escaped character through as a literal.
wrt.disableOutputEscaping = True
cnth.startElement "", "", "company", atrs
cnth.characters "GG&amp;G"
cnth.endElement "", "", "company"

'ends the document
cnth.endDocument

MsgBox wrt.output
End Sub

Example Output

The output in the TextResult.text box is as follows. Notice that that the "&" character has been escaped twice in the first <company> element and passed through as intended (shown in bold) in the second <company> element.

<?xml version="1.0" encoding="UTF-16" standalone="no"?>

<company>GG&amp;amp;G</company>

<company>GG&amp;G</company>

[C/C++]

Syntax

[propput]
HRESULT disableOutputEscaping (
  [in] VARIANT_BOOL fValue);
[propget]
HRESULT disableOutputEscaping (
  [out, retval] VARIANT_BOOL * fValue);

Parameters

fValue
Boolean.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

If this property is set to True, the XML output may not be well-formed or valid. The disableOutputEscaping property has no effect for DOM output.

Value | Description
True | Writer cannot escape input when writing output.
False (default) | Writer should escape input when writing output.

See Also

MXHTMLWriter Coclass | MXXMLWriter Coclass

Applies to: IMXWriter Interface


encoding Property

[This is preliminary documentation and subject to change.]

Sets and gets encoding for the output.

[Visual Basic]

Implementation Syntax

Property Let IMXWriter_encoding(ByVal RHS As String)
Property Get IMXWriter_encoding() As String

Usage Syntax

oMXXMLWriter.encoding = strValue
strValue = oMXXMLWriter.encoding

Remarks

String. Read/write. The default string is dependent on implementation. Microsoft® Visual Basic® strings are always UTF-16 encoded. The encoding property has no effect for BSTR or DOM output.

[C/C++]

Syntax

[propput]
HRESULT encoding (
  [in] BSTR strEncoding);

[propget]
HRESULT encoding (
  [out, retval] BSTR * strEncoding);

Parameters

strEncoding
The BSTR used to identify encoding.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

Read/write. The default string is dependent on implementation. The encoding property has no effect for BSTR or DOM output.

See Also

Character Encoding, XML, and MSXML | MXHTMLWriter Coclass | MXXMLWriter Coclass

Applies to: IMXWriter Interface


indent Property

[This is preliminary documentation and subject to change.]

Sets whether to indent output. When set to True, this property requires output to be indented (or "pretty printed") to reflect the nesting structure of the document.

Note The indent property has a special effect on white space processing when writer output is specified as a DOMDocument object. For more information, see Create a DOMDocument Object from SAX Events.
[Visual Basic]

Implementation Syntax

Property Let IMXWriter_indent(ByVal RHS As Boolean)
Property Get IMXWriter_indent() As Boolean

Usage Syntax

oMXXMLWriter.indent = boolValue
boolValue = oMXXMLWriter.indent

Remarks

Read/write. A Boolean expression (True/False) specifying whether the feature is on or off.

[C/C++]

Syntax

[propput]
HRESULT indent (
  [in] VARIANT_BOOL fIndentMode);

[propget]
HRESULT indent (
  [out, retval] VARIANT_BOOL * fIndentMode);

Parameters

fIndentMode
A Boolean expression (True/False) specifying whether the feature is on or off.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

The default of this property depends on the implementation. There is no way to detect white space inside an internal document type definition (DTD). Therefore, DTDs are always indented.

Value | Description
True | Provide white space for formatting.
False | No additional indenting requirement.

See Also

MXHTMLWriter Coclass | MXXMLWriter Coclass

Applies to: IMXWriter Interface


omitXMLDeclaration Property

[This is preliminary documentation and subject to change.]

Forces the IMXWriter to skip the XML declaration. This can be useful when you want to output fragments of larger XML documents that can be assembled into a single XML document later.

[Visual Basic]

Implementation Syntax

Property Let IMXWriter_omitXMLDeclaration(ByVal RHS As Boolean)
Property Get IMXWriter_omitXMLDeclaration() As Boolean

Usage Syntax

oMXXMLWriter.omitXMLDeclaration= boolValue
boolValue = oMXXMLWriter.omitXMLDeclaration

Remarks

Read/write. A Boolean expression (True/False) specifying whether the feature is on or off. The omitXMLDeclaration property has no effect on DOM output.

[C/C++]

Syntax

[propput]
HRESULT omitXMLDeclaration (
  [in] VARIANT_BOOL fValue);
[propget]
HRESULT omitXMLDeclaration (
  [out, retval] VARIANT_BOOL * fValue);

Parameters

fValue
Boolean.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

Value | Description
True | Omit XML declaration.
False (default) | Provide XML declaration.

The omitXMLDeclaration property has no effect on DOM output.

[Visual Basic]

Example

The following example loads the books.xml file and generates an XML document without the XML declaration.

Dim rdr As New MSXML2.SAXXMLReader
Dim cnth As IVBSAXContentHandler
Dim wrt As New MXXMLWriter
wrt.indent = True
wrt.omitXMLDeclaration = True
wrt.byteOrderMark = False
Set cnth = wrt
Set rdr.contentHandler = cnth
rdr.parseURL ("books.xml")
MsgBox wrt.output

Results

The following shows a fragment of books.xml with the XML declaration omitted from the output.

<catalog>

<book id="bk101">

<author>Gambardella, Matthew</author>

<title>XML Developer's Guide</title>

<genre>Computer</genre>

<price>44.95</price>

<publish_date>2000-10-01</publish_date>

<release_years>1998 2000</release_years>

<description>An in-depth look at creating applications with XML.</description>

</book>

See Also

MXHTMLWriter Coclass | MXXMLWriter Coclass | Sample XML File (books.xml)

Applies to: IMXWriter Interface


output Property

[This is preliminary documentation and subject to change.]

Sets the destination and the type of output for IMXWriter. By default, the output property is a BSTR (string) value. Output can be:

  • any implementation of the IStream interface. (The resulting document will be written into the provided IStream).
  • String.
  • DOMDocument object.

    For more information about setting the output property to a DOMDocument object, see Create a DOMDocument Object from SAX Events.

Setting this property to the empty value (VT_EMPTY or " ") will return output to the internal string and reset it.

[Visual Basic]

Implementation Syntax

Private Property Let IMXWriter_output(ByVal RHS As Variant)
Private Property Get IMXWriter_output() As Variant

Usage Syntax

oMXXMLWriter.output = varDestination
varDestination = oMXXMLWriter.output

Remarks

Read/write. Variant destination.

Example

The following example creates an instance of MXXMLWriter and sets it to the ContentHandler. Method calls on the ContentHandler are used to manually generate a document. In the sample, a DOMDocument object is created, and the writer output is set to the DOMDocument object. After the contents of the output property are loaded into a DOMDocument object, they are then displayed in message box.

Dim wrt As New MXXMLWriter
Dim cnth As IVBSAXContentHandler
Dim atrs As New SAXAttributes
Dim xmlDoc As New DOMDocument
Dim currNode As IXMLDOMNode

Set cnth = wrt
wrt.output = xmlDoc
cnth.startDocument

cnth.startElement "", "", "catalog", atrs
atrs.addAttribute "", "", "id", "CDATA", "bk101"
cnth.startElement "", "", "book", atrs
atrs.Clear

cnth.startElement "", "", "author", atrs
cnth.characters "Gambardella, Matthew"
cnth.endElement "", "", "author"

cnth.startElement "", "", "title", atrs
cnth.characters "XML Developer's Guide"
cnth.endElement "", "", "title"

cnth.startElement "", "", "description", atrs
cnth.characters "An in-depth look at creating applications with XML"
cnth.endElement "", "", "description"

cnth.endElement "", "", "book"
cnth.endElement "", "", "catalog"

'ends the document
cnth.endDocument

Set currNode = xmlDoc.documentElement.childNodes.Item(0)
MsgBox currNode.nodeName
[C/C++]

Syntax

[propput]
HRESULT output (
  [in] VARIANT varDestination);

[propget]
HRESULT output (
  [out, retval] VARIANT * varDestination);

Parameters

varDestination
The variant destination.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

The default is VT_EMPTY to output to string.

See Also

MXHTMLWriter Coclass | MXXMLWriter Coclass

Applies to: IMXWriter Interface


standalone Property

[This is preliminary documentation and subject to change.]

Sets the value of the standalone attribute in the XML declaration to "yes" or "no".

[Visual Basic]

Implementation Syntax

Property Let IMXWriter_standalone(ByVal RHS As Boolean)
Property Get IMXWriter_standalone() As Boolean

Usage Syntax

oMXXMLWriter.standalone = boolValue
boolValue = oMXXMLWriter.standalone

Remarks

Boolean. Read/write.

Example

The following example reads books.xml and writes the value of the standalone attribute to "yes" in the XML declaration.

Dim rdr As New MSXML2.SAXXMLReader
Dim cnth As IVBSAXContentHandler
Dim wrt As New MXXMLWriter
wrt.indent = True
wrt.standalone = True
Set cnth = wrt
Set rdr.contentHandler = cnth
rdr.parseURL ("books.xml")
MsgBox wrt.output
[C/C++]

Syntax

[propput]
HRESULT standalone (
  [in] VARIANT_BOOL fValue);

[propget]
HRESULT standalone (
  [out, retval] VARIANT_BOOL * fValue);

Parameters

fValue
Boolean.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

Value | Description
True | Sets the value of the standalone attribute to "yes".
False (default) | Sets the value of the standalone attribute to "no".

See Also

MXHTMLWriter Coclass | MXXMLWriter Coclass | Sample XML File (books.xml)

Applies to: IMXWriter Interface


version Property

[This is preliminary documentation and subject to change.]

Specifies the version to include in XML declarations, for example, <?xml version="1.0">.

[Visual Basic]

Implementation Syntax

Property Let IMXWriter_version(ByVal RHS As String)
Property Get IMXWriter_version() As String

Usage Syntax

oMXXMLWriter.version = strVersion
strVersion = oMXXMLWriter.version
[C/C++]

Syntax

[propput]
HRESULT version (
  [in] BSTR strVersion);
[propget]
HRESULT version (
  [out, retval] BSTR * strVersion);

Parameters

strVersion
The BSTR of version.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

Read/write. A string representing the version. The default value is "1.0".

See Also

MXHTMLWriter Coclass | MXXMLWriter Coclass

Applies to: IMXWriter Interface


MXHTMLWriter Coclass

[This is preliminary documentation and subject to change.]

MXHTMLWriter generates HTML output from Simple API for XML (SAX) events and handles many of the details of outputting content in HTML format. When connected to SAXXMLReader, and set as a ContentHandler, MXHTMLWriter accumulates content passed by events thrown by the reader. This content is stored in the output buffer of MXHTMLWriter. The MXXMLWriter coclass implements the IMXWriter interface. MXXMLWriter provides version-independent and version-dependent coclasses.

MXHTMLWriter

The version-independent coclass. Uses the most current implementation.

(CLSID_MXHTMLWriter: a4c23ec3-6b70-4466-9127-550077239978)

MXHTMLWriter30

The version 3.0-dependent coclass.

(CLSID_MXHTMLWriter: 853d1540-c1a7-4aa9-a226-4d3bd301146d)

MXHTMLWriter40

The version 4.0-dependent coclass.

(CLSID_MXHTMLWriter: 88d969c9-f192-11d4-a65f-0040963251e5)

Results generated by MXHTMLWriter are exposed through the MXHTMLWriter.output property. MXHTMLWriter provides several properties that enable you to modify the results generated by MXHTMLWriter. For example, to enable "pretty printing," set the MXHTMLWriter.indent to True.

To enable MXHTMLWriter to catch handler events passed by SAXXMLReader, you must set MXHTMLWriter as the ContentHandler, and optionally as any of the other handlers. The following table shows the handler interfaces implemented by MXHTMLWriter.

Visual Basic Interfaces | C++ Interfaces
IVBSAXContentHandler | ISAXContentHandler
IVBSAXDeclHandler | ISAXDeclHandler
IVBSAXDTDHandler | ISAXDTDHandler
IVBSAXErrorHandler | ISAXErrorHandler
IVBSAXLexicalHandler | ISAXLexicalHandler

With MXHTMLWriter, HTML is output according to the HTML output method, as defined in the XSL Transformations (XSLT) Version 1.0 recommendation.

In general, MXHTMLWriter outputs HTML content like XML, with the following exceptions:

  • The following elements are recognized as empty elements. They are recognized in any combination of uppercase and lowercase. These elements are output with a start tag but no end tag.

    <area> | <frame> | <links>
    <base> | <hr> | <meta>
    <basefont> | <img> | <param>
    <br> | <input>
    <col> | <isindex>

  • The <script> and <style> elements do not require escaping of special characters. In the textual content of these elements, a "<" character will be output as "<", not as "&lt;".
  • HTML attributes that have a URI value, such as the href attribute of the <a> element or the src attribute of the <image> element, are recognized. Special characters within a URI are escaped as specified in the HTML specification. For example, nonASCII characters in the URI should be represented by converting each byte of the UTF-8 representation "%hh" where hh represents the byte value in hexidecimal. For example, spaces are represented as "%20".
  • MXHTMLWriter may output a character using a character entity reference if one is defined for it in the version of HTML that is specified.
  • Processing instructions are terminated with ">" rather than "?>".
  • Attributes that are written with a keyword only, and no value, will be recognized and output in this form. For example, in HTML, <OPTION SELECTED> shorthand is acceptable, but in XML it must be written as <OPTION SELECTED="SELECTED">. The HTML output method will normally use the abbreviated form, as this is the only form recognized by earlier HTML browsers.
  • The special use of the ampersand character in dynamic HTML attributes is recognized. For example, although the tag <TD HEIGHT=&{height};" is valid HTML, it would not be valid XML because of the ampersand character.

Properties

byteOrderMark | Determines whether or not to write the Byte Order Mark (BOM).
disableOutputEscaping | Determines whether disableOutputEscaping is on or off. When set to True, special symbols such as "&" are passed through literally.
encoding | Sets encoding for the output.
indent | Sets whether to indent output. Useful for "pretty printing."
omitXMLDeclaration | Not supported by MXHTMLWriter.
output | Sets the destination for the output generated by MXHTMLWriter.
standalone | Not supported by MXHTMLWriter.
version | Not supported by MXHTMLWriter.

Methods

flush Flushes the object's internal buffer to its destination IStream/string.

Requirements

[Visual Basic, C/C++]

Implementation: msxml4.dll, msxml2.lib

Header and LIB files: msxml2.h, msxml2.lib

[Visual Basic, C/C++]

Other Resources Other Resources

W3C XSL Transformations (XSLT) Version 1.0 Recommendation


flush Method

[This is preliminary documentation and subject to change.]

Flushes the object's internal buffer to its destination IStream/string. This flushing occurs when one of the following conditions is met:

  • The output property is set to a destination.
  • The endDocument() event is called.
  • The flush() method is called.
[Visual Basic]

Usage Syntax

oMXHTMLWriter.flush
[C/C++]

Syntax

HRESULT flush ( );

Return Values

S_OK

Remarks

Avoid handling the underlying IStream object during output (for example, direct writing). When using the flush method, the exact position within the generated document is not generally known. If the flush method is called, all output that has been processed is put into the underlying IStream/ISequentialStream object.

See Also

output Property | IMXWriter Interface | MXXMLWriter Coclass

Applies to: MXHTMLWriter Coclass


byteOrderMark Property

[This is preliminary documentation and subject to change.]

Determines whether to write the Byte Order Mark (BOM) to the MXHTMLWriter output. Setting the byteOrderMark property to False prohibits the MXHTMLWriter from putting the Byte Order Mark (BOM) into the resulting HTML document.

[Visual Basic]

Usage Syntax

oMXXMLWriter.byteOrderMark = boolValue
boolValue = oMXXMLWriter.byteOrderMark

Remarks

Boolean. Read/write. The default is True. MXHTMLWriter never generates a BOM if the output is set to a string.

[C/C++]

Syntax

[proput]
HRESULT byteOrderMark (
  [in] VARIANT_BOOL fWriteByteOrderMark);
[propget]
HRESULT byteOrderMark (
  [out, retval] VARIANT_BOOL * fWriteByteOrderMark);

Parameters

fWriteByteOrderMark
A Boolean expression (True/False) specifying whether the feature is on or off.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

The default is True. MXHTMLWriter never outputs BOM if the output is set to a string.

Value | Description
True | MXHTMLWriter follows HTML 4.0 specifications and outputs BOM for encoding.
False | MXHTMLWriter does not write the BOM into the resulting HTML output.

See Also

IMXWriter Interface | MXXMLWriter Coclass

Applies to: MXHTMLWriter Coclass


disableOutputEscaping Property

[This is preliminary documentation and subject to change.]

Specifies whether the disableOutputEscaping is on or off. When set to True, special symbols, such as "&", are passed through literally. When disableOutputEscaping is set to False, special symbols, (also known as built-in entities), such as "&", are escaped to &amp;.

[Visual Basic]

Usage Syntax

oMXXMLWriter.disableOutputEscaping = boolValue
boolValue = oMXXMLWriter.disableOutputEscaping

Remarks

Boolean. Read/write. The default value is False. Normally, when you try to output a special character such as "<" or "&", the special character will be escaped in the output file using the standard XML escaping mechanism. For example, by default, MXHTMLWriter writes the "&" symbol as "&amp;". If disableOutputEscaping is set to True, the XML parser does not escape the special symbol and writes the "&" symbol as the literal "&".

Example

For elements such as <script> and <style>, MXHTMLWriter passes through special characters. For others, you may want to set disableOutputEscaping property to True, as shown in the following example.

Dim wrt As New MXHTMLWriter
Dim cnth As IVBSAXContentHandler
Dim atrs As New SAXAttributes
Set cnth = wrt

cnth.startDocument
cnth.startElement "", "", "html", atrs
cnth.startElement "", "", "script", atrs
cnth.characters "var a = 0;"
cnth.characters "var b = 1;"
cnth.characters "if (a < b) alert('hello')"
cnth.endElement "", "", "script"
cnth.startElement "", "", "body", atrs
wrt.disableOutputEscaping = True
cnth.characters "GG&G"
wrt.disableOutputEscaping = False
cnth.endElement "","","body"
cnth.endElement "","","html"
MsgBox wrt.output

Example Output

The preceding example code passes through the "<" character as a literal within the <script> tags. However, to pass through the "&" character in the company name GG&G, you must set the disableOutputEscaping property to True. If disableOutputEscaping is set to False, the "&" character is escaped as &amp;.

<html><script>var a = 0;var b = 1;if (a < b) alert('hello')</script>
   <body>GG&G
   </body>
</html>
[C/C++]

Syntax

[propput]
HRESULT disableOutputEscaping (
  [in] VARIANT_BOOL fValue);
[propget]
HRESULT disableOutputEscaping (
  [out, retval] VARIANT_BOOL * fValue);

Parameters

fValue
A Boolean expression (True/False) specifying whether the feature is on or off.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

If this property is set to True, the XML output may not be well-formed or valid.

Value | Description
True | MXXMLWriter does not escape special symbols (passing them through as literals) when writing output.
False (default) | MXXMLWriter escapes special symbols when writing output.

See Also

IMXWriter Interface | MXXMLWriter Coclass

Applies to: MXHTMLWriter Coclass


encoding Property

[This is preliminary documentation and subject to change.]

Allows you to set the encoding according to HTML 4.0 specifications. MXHTMLWriter supports the same encoding as the Microsoft XML Parser (MSXML) DOM. This parameter is ignored for output to a BSTR, but will take effect if output is changed in the middle of a document to a destination other than BSTR.

[Visual Basic]

Usage Syntax

oMXXMLWriter.encoding = strValue
strValue = oMXXMLWriter.encoding

Remarks

String. This property is read/write. The default is UTF-16. If your output is a string, the encoding parameter is ignored.

[C/C++]

Syntax

[propput]
HRESULT encoding (
  [in] BSTR strEncoding);
[propget]
HRESULT encoding (
  [out, retval] BSTR * strEncoding);

Parameters

strEncoding
The BSTR used to identify encoding.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

The default string is UTF-16. If your output is a string, the encoding parameter is ignored.

See Also

Character Encoding, XML, and MSXML | IMXWriter Interface | MXXMLWriter Coclass

Applies to: MXHTMLWriter Coclass


indent Property

[This is preliminary documentation and subject to change.]

Sets whether to indent output. When set to True, this property requires output to be indented (or "pretty printed") to reflect the nesting structure of the document.

[Visual Basic]

Usage Syntax

oMXXMLWriter.indent = boolValue
boolValue = oMXXMLWriter.indent

Remarks

Boolean. Read/write. The general rules of indentation are: XML headers and root elements start on a new line with a zero indent; element content, including leading and trailing white spaces, is not changed in any way.

Example

The following example creates a simple HTML document and indents it for "pretty-printing."

Code sample

Dim wrt As New MXHTMLWriter
Dim cnth As IVBSAXContentHandler
Dim atrs As New SAXAttributes
Set cnth = wrt
wrt.indent = True
cnth.startDocument
cnth.startElement "", "", "html", atrs
cnth.startElement "", "", "body", atrs
cnth.characters "This is a test"
cnth.endElement "", "", "body"
cnth.endElement "", "", "html"
MsgBox wrt.output

Results

<html>
    <body>This is a test
    </body>
</html>
[C/C++]

Syntax

[propput]
HRESULT indent (
  [in] VARIANT_BOOL fIndentMode);
[propget]
HRESULT indent (
  [out, retval] VARIANT_BOOL * fIndentMode);

Parameters

fIndentMode
A Boolean expression (True/False) specifying whether the feature is on or off.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

The default of this property depends on the implementation. The general rules of indentation are: XML headers and root elements start on a new line with a zero indent; element content, including leading and trailing white spaces, is not changed in any way.

See Also

IMXWriter Interface | MXXMLWriter Coclass

Applies to: MXHTMLWriter Coclass


omitXMLDeclaration Property

[This is preliminary documentation and subject to change.]

This property is not supported by MXHTMLWriter.


output Property

[This is preliminary documentation and subject to change.]

Determines the output for MXXMLWriter. By default, the output property is a BSTR (string) value. You can also set this property to any implementation of the IStream interface, and the resulting document will be written into the provided IStream. Setting this property to the empty value (VT_EMPTY or " ") will return output to the internal string and reset it.

[Visual Basic]

Usage Syntax

oMXXMLWriter.output = varDestination
varDestination = oMXXMLWriter.output

Remarks

Read/write. Variant destination.

Example

For elements such as <script> and <style>, MXHTMLWriter passes through special characters. In the following example, MXHTMLWriter passes through the "<" character as a literal within the <script> tags.

Dim wrt As New MXHTMLWriter
Dim cnth As IVBSAXContentHandler
Dim atrs As New SAXAttributes
Set cnth = wrt
cnth.startDocument
cnth.startElement "", "", "html", atrs
cnth.startElement "", "", "script", atrs
cnth.characters "var a = 0;"
cnth.characters "var b = 1;"
cnth.characters "if (a < b) alert('hello')"
cnth.endElement "", "", "script"
cnth.startElement "", "", "body", atrs
wrt.disableOutputEscaping = True
cnth.characters "Sample HTML Page"
wrt.disableOutputEscaping = False
cnth.endElement "", "", "body"
cnth.endElement "", "", "html"
MsgBox wrt.output

Example Output

[C/C++]

Syntax

[propput]
HRESULT output (
  [in] VARIANT varDestination);
[propget]
HRESULT output (
  [out, retval] VARIANT * varDestination);

Parameters

varDestination
The variant destination.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

The default is VT_EMPTY to output to string.

See Also

IMXWriter Interface | MXXMLWriter Coclass

Applies to: MXHTMLWriter Coclass


standalone Property

[This is preliminary documentation and subject to change.]

This property is not supported by MXHTMLWriter.


version Property

[This is preliminary documentation and subject to change.]

This property is not supported by MXHTMLWriter.


MXXMLWriter Coclass

[This is preliminary documentation and subject to change.]

MXXMLWriter generates XML output that can be:

  • Any implementation of the IStream interface. (The resulting document will be written into the provided IStream.)
  • A string
  • A DOMDocument object. For more information about setting the output property to a DOMDocument object, see Create a DOMDocument Object from SAX Events

When connected to SAXXMLReader, and set as a ContentHandler, MXXMLWriter accumulates XML content passed by events thrown by the reader. This content is stored in the MXXMLWriter's output buffer. The MXXMLWriter coclass implements the IMXWriter interface. MXXMLWriter provides version-independent and version-dependent coclasses.

MXXMLWriter
The version-independent coclass. Uses the most current implementation.

(CLSID_MXXMLWriter: fc220ad8-a72a-4ee8-926e-0b7ad152a020)

MXXMLWriter30
The version 3.0-dependent coclass.

(CLSID_MXXMLWriter30: 3d813dfe-6c91-4a4e-8f41-04346a841d9c)

MXXMLWriter40
The version 4.0-dependent coclass.

(CLSID_MXXMLWriter40: 8d969c8-f192-11d4-a65f-0040963251e5)

In addition to generating XML, MXXMLWriter also handles the details of collecting data produced by SAX events. For example, rather than concatenating strings within each method call of the ContentHandler, and dealing with issues such as the manual insertion of opening and closing brackets for startElement and EndElement events respectively, you can set MXXMLWriter to the IVBSAXContentHandler\ISAXContentHandler interface, and then make method calls on the ContentHandler to push data to MXXMLWriter. MXXMLWriter then writes opening brackets for the startElement event and closing brackets for the endElement event.

Results generated by MXXMLWriter are exposed through the MXXMLWriter.output property. MXXMLWriter provides several properties that enable you to modify output collected by MXXMLWriter. For example, to create an XML document fragment, set the MXXMLWriter.omitXMLDeclaration to True. In a similar way, you can set the MXXMLWriter.indent to True to enable "pretty printing."

To enable MXXMLWriter to catch handler events passed by SAXXMLReader, you set MXXMLWriter as the ContentHandler, and optionally as any of the other handlers. For more information about how to register MXXMLWriter as a handler, see Use MXXMLWriter.

The following table shows the handler interfaces implemented by MXXMLWriter.

Visual Basic Interfaces | C++ Interfaces
IVBSAXContentHandler | ISAXContentHandler
IVBSAXDeclHandler | ISAXDeclHandler
IVBSAXDTDHandler | ISAXDTDHandler
IVBSAXErrorHandler | ISAXErrorHandler
IVBSAXLexicalHandler | ISAXLexicalHandler

Properties

byteOrderMark | Determines whether to write the Byte Order Mark (BOM).
disableOutputEscaping | Turns disableOutputEscaping on or off. When disableOutputEscaping is set to True, special symbols such as "&" are passed through literally.
encoding | Sets and gets encoding for the output.
indent | Sets whether to indent output. Useful for "pretty printing."
omitXMLDeclaration | Forces the MXXMLWriter to omit the XML declaration. Useful for creating document fragments.
output | Determines the destination and the type of output for MXXMLWriter. Output can be stream, string, or DOM.
standalone | Sets the value of the standalone attribute in the XML declaration to "yes" or "no".
version | Specifies the version to include in XML declaration.

Methods

flush Flushes the object's internal buffer to its destination IStream/string.

Requirements

[Visual Basic]

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and LIB files: msxml2.h, msxml2.lib


flush Method

[This is preliminary documentation and subject to change.]

Flushes the object's internal buffer to its destination IStream/string. This flushing occurs when one of the following conditions is met:

  • The output property is set to a destination.
  • The endDocument() event is called.
  • The flush() method is called.
[Visual Basic]

Usage Syntax

oMXXMLWriter.flush

Remarks

Avoid handling the underlying IStream object during output (for example, direct writing). When using the flush method, the exact position within the generated document is not generally known. If the flush method is called, all output that has been processed is put into the underlying IStream/ISequentialStream object.

[C/C++]

Syntax

HRESULT flush ( );

Return Values

S_OK

Remarks

Avoid handling the underlying IStream object during output (for example, direct writing). When using the flush method, the exact position within the generated document is not generally known. If the flush method interrupts MXXMLWriter output, all output that has been processed is put into the underlying IStream/ISequentialStream object.

See Also

output Property

Applies to: MXXMLWriter Coclass


byteOrderMark Property

[This is preliminary documentation and subject to change.]

Determines whether to write the Byte Order Mark (BOM) to MXXMLWriter output. Setting the byteOrderMark property to False prohibits the writer from putting the Byte Order Mark (BOM) into the resulting XML document or document fragment. This property is useful for creating document fragments. Setting this property to True makes MXXMLWriter follow XML 1.0 specifications and output the Byte Order Mark for appropriate encoding.

[Visual Basic]

Usage Syntax

oMXXMLWriter.byteOrderMark = boolValue
boolValue = oMXXMLWriter.byteOrderMark

Remarks

Boolean. Read/write. The default is True. MXXMLWriter never generates a BOM if the output is set to a string.

[C/C++]

Syntax

[proput]
HRESULT byteOrderMark (
  [in] VARIANT_BOOL fWriteByteOrderMark);

[propget]
HRESULT byteOrderMark (
  [out, retval] VARIANT_BOOL * fWriteByteOrderMark);

Parameters

fWriteByteOrderMark
A Boolean expression (True/False) specifying whether the feature is on or off.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

The default of this is True. MXXMLWriter never outputs BOM if the output is set to a string.

Value | Description
True | MXMXLWriter follows XML 1.0 specifications and outputs BOM for encoding.
False | MXMXLWriter does not write the BOM into the resulting XML output.

Example

In some cases, you may want to merge an XML document fragment with an XML document. If the document fragment has not been parsed, the "&" character will be escaped as "&amp;" in the document fragment. However, if you merge the document fragment into an XML document, the "&amp;" will be escaped again when it is parsed. To avoid the situation in which an already escaped character is escaped again, set the disableOutputEscaping property to True. The following code sample manually generates an XML document to demonstrate how this works. For the first element created, disableOutputEscaping is left as False, resulting in a double-escaped character. However, in the second element generated, disableOutputEscaping is set to True, enabling the "GG&amp;G" value to be passed through as intended.

Dim wrt As New MXXMLWriter
Dim cnth As IVBSAXContentHandler
Dim atrs As New SAXAttributes
Set cnth = wrt

'Starts the document by addding the XML declaration.
cnth.startDocument

'This section escapes the character.
cnth.startElement "", "", "company", atrs
cnth.characters "GG&amp;G"
cnth.endElement "", "", "company"

'This section passes the escaped character through as a literal.
wrt.disableOutputEscaping = True
cnth.startElement "", "", "company", atrs
cnth.characters "GG&amp;G"
cnth.endElement "", "", "company"

'Ends the document.
cnth.endDocument

'Sets the writer output to the TextResult.Text box.
MsgBox wrt.output

Example Output

The output in the message box is as follows. Notice that the "&" character has been escaped twice in the first <company> element and passed through as intended (shown in bold) in the second <company> element.

<?xml version="1.0" encoding="UTF-16" standalone="no"?>

<company>GG&amp;amp;G</company>

<company>GG&amp;G</company>

See Also

Applies to: MXXMLWriter Coclass


disableOutputEscaping Property

[This is preliminary documentation and subject to change.]

Turns disableOutputEscaping on or off. When disableOutputEscaping is set to True, special symbols such as "&" are passed through literally. When disableOutputEscaping is set to False, special symbols (also known as built-in entities) such as & are escaped to &amp;.

[Visual Basic]

Usage Syntax

oMXXMLWriter.disableOutputEscaping = boolValue
boolValue = oMXXMLWriter.disableOutputEscaping

Remarks

Read/write. The default value is False. When you try to output a special character such as "<" or "&", the special character will be escaped in the output file using the standard XML escaping mechanism. For example, by default, the MXXMLWriter writes the "&" symbol as "&amp;" unless disableOutputEscaping is set to True. If disableOutputEscaping is set to True, MXXMLWriter does not escape the special symbol and writes the "&" symbol as the literal "&".

[C/C++]

Syntax

[propput]
HRESULT disableOutputEscaping (
  [in] VARIANT_BOOL fValue);
[propget]
HRESULT disableOutputEscaping (
  [out, retval] VARIANT_BOOL * fValue);

Parameters

fValue
A Boolean expression (True/False) specifying whether the feature is on or off.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

If this property is set to True, the XML output may not be well-formed or valid.

Value | Description
True | MXXMLWriter does not escape special symbols (passing them through as literals) when writing output.
False (default) | MXXMLWriter escapes special symbols when writing output.

See Also

Applies to: MXXMLWriter Coclass


encoding Property

[This is preliminary documentation and subject to change.]

Sets and gets encoding for the output.

[Visual Basic]

Usage Syntax

oMXXMLWriter.encoding = strValue
strValue = oMXXMLWriter.encoding

Remarks

String. Read/write. The default string is empty, that is, UTF-16. Microsoft® Visual Basic® strings are always UTF-16 encoded. If your output is a string, the encoding parameter is ignored.

[C/C++]

Syntax

[propput]
HRESULT encoding (
  [in] BSTR strEncoding);

[propget]
HRESULT encoding (
  [out, retval] BSTR * strEncoding);

Parameters

strEncoding
The BSTR used to identify encoding.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

The default string is empty, that is, UTF-16.

If your output is a string, the encoding parameter is ignored.

See Also

Character Encoding, XML, and MSXML

Applies to: MXXMLWriter Coclass


indent Property

[This is preliminary documentation and subject to change.]

Sets whether to indent output. When set to True, this property indents output for "pretty printing" to reflect the nesting structure of the document.

[Visual Basic]

Usage Syntax

oMXXMLWriter.indent = boolValue
boolValue = oMXXMLWriter.indent

Remarks

Boolean. Read/write. The default is False. The general rules of indenting elements are: XML headers and root elements start on a new line with a zero indent; element content, including leading and trailing white spaces, is not changed in any way.

Example

The following example parses books.xml and indents the output.

Dim rdr As New MSXML2.SAXXMLReader
Dim cnth As IVBSAXContentHandler
Dim wrt As New MXXMLWriter
wrt.indent = True
wrt.standalone = True
Set cnth = wrt
Set rdr.contentHandler = cnth
rdr.parseURL ("books.xml")
MsgBox wrt.output

Results

The following shows the beginning of the books.xml output with the elements indented for "pretty printing".

<?xml version="1.0" encoding="UTF-16" standalone="yes"?>

<catalog>

<book id="bk101">

<author>Gambardella, Matthew</author>

<title>XML Developer's Guide</title>

<genre>Computer</genre>

<price>44.95</price>

<publish_date>2000-10-01</publish_date>

<description>An in-depth look at creating applications with XML.</description>

</book>

[C/C++]

Syntax

[propput]
HRESULT indent (
  [in] VARIANT_BOOL fIndentMode);

[propget]
HRESULT indent (
  [out, retval] VARIANT_BOOL * fIndentMode);

Parameters

fIndentMode
A Boolean expression (True/False) specifying whether the feature is on or off.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

The default of this property is False. Because there is no way to detect white space inside an internal document type definition (DTD), they are always indented.

Value | Description
True | Provide white space for formatting.
False | No additional indenting requirement.

See Also

Sample XML File (books.xml)

Applies to: MXXMLWriter Coclass


omitXMLDeclaration Property

[This is preliminary documentation and subject to change.]

Forces the MXXMLWriter to omit the XML declaration. This property can be used to output fragments of larger XML documents that can be assembled into a single XML document later.

[Visual Basic]

Usage Syntax

oMXXMLWriter.omitXMLDeclaration= boolValue
boolValue = oMXXMLWriter.omitXMLDeclaration

Remarks

Boolean. Read/write.

Example

The following example parses books.xml and generates an XML document without the XML declaration.

Dim rdr As New MSXML2.SAXXMLReader
Dim cnth As IVBSAXContentHandler
Dim wrt As New MXXMLWriter
wrt.indent = True
wrt.omitXMLDeclaration = True
wrt.byteOrderMark = False
Set cnth = wrt
Set rdr.contentHandler = cnth
rdr.parseURL ("books.xml")
MsgBox wrt.output

Results

The following shows a fragment of books.xml with the XML declaration omitted from the output.

<catalog>

<book id="bk101">

<author>Gambardella, Matthew</author>

<title>XML Developer's Guide</title>

<genre>Computer</genre>

<price>44.95</price>

<publish_date>2000-10-01</publish_date>

<release_years>1998 2000</release_years>

<description>An in-depth look at creating applications with XML.</description>

</book>

[C/C++]

Syntax

[propput]
HRESULT omitXMLDeclaration (
  [in] VARIANT_BOOL fValue);
[propget]
HRESULT omitXMLDeclaration (
  [out, retval] VARIANT_BOOL * fValue);

Parameters

fValue
Boolean. Read/write.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

Value | Description
True | Omit XML declaration.
False (default) | Provide XML declaration.

See Also

Sample XML File (books.xml)

Applies to: MXXMLWriter Coclass


output Property

[This is preliminary documentation and subject to change.]

Determines the destination and the type of output for MXXMLWriter. By default, the output property is a BSTR (string) value.

Output for IMXWriter can be set as one of the following:

  • Any implementation of the IStream interface. (The resulting document will be written into the provided IStream.)
  • A string.
  • A DOMDocument object.

    For more information about setting the output property to a DOMDocument object, see Create a DOMDocument Object from SAX Events

Setting the output property to the empty value (VT_EMPTY or " ") will return output to the internal string and reset it.

[Visual Basic]

Usage Syntax

oMXXMLWriter.output = varDestination
varDestination = oMXXMLWriter.output

Remarks

Read/write. Variant destination.

Example

The following example creates an instance of MXXMLWriter and sets it to the ContentHandler. Method calls on the ContentHandler are used to manually generate a document. In the sample, a DOMDocument object is created, and the writer output is set to the DOMDocument object. The example code produces three message boxes. The first box shows the DOMDocument object as it is being built (For example, <catalog><book id="bk101"/></catalog>). The second message box shows the finished document. The third message box shows the text in the first <author> tag, Gambardella, Matthew.

Dim xmlDoc As New MSXML2.DOMDocument
Dim nodeList As IXMLDOMNodeList
Dim wrt As New MXXMLWriter
Dim cnth As IVBSAXContentHandler
Dim atrs As New SAXAttributes

Set cnth = wrt

wrt.output = xmlDoc

'sets standalone="yes" in the XML declaration
'wrt.standalone = True
'configures the writer to indent elements
wrt.indent = True

'starts the document by addding the XML declaration
cnth.startDocument

'adds the <catalog> element to the page
cnth.startElement "", "", "catalog", atrs

'adds the id attribute to the collection witht he "bk0101" value.
atrs.addAttribute "", "", "id", "CDATA", "bk101"
'creates the <book id="bk101"> tag
cnth.startElement "", "", "book", atrs
'clears the attribute collection
atrs.Clear

MsgBox xmlDoc.xml

'creates the <author>Gambardella, Matthew</author> string
cnth.startElement "", "", "author", atrs
cnth.characters "Gambardella, Matthew"
cnth.endElement "", "", "author"

'creates the <title>XML Developer's Guide</title> string
cnth.startElement "", "", "title", atrs
cnth.characters "XML Developer's Guide"
cnth.endElement "", "", "title"

'creates the <description>An in-depth look at...</description> string
cnth.startElement "", "", "description", atrs
cnth.characters "An in-depth look at creating applications with XML"
cnth.endElement "", "", "description"

'adds closing tags for <book> and <catalog> elements
cnth.endElement "", "", "book"
cnth.endElement "", "", "catalog"

'ends the document
cnth.endDocument

'displays the author's name in a message box
MsgBox xmlDoc.xml
Set objNodeList = xmlDoc.getElementsByTagName("author")
MsgBox objNodeList.Item(0).Text
[C/C++]

Syntax

[propput]
HRESULT output (
  [in] VARIANT varDestination);

[propget]
HRESULT output (
  [out, retval] VARIANT * varDestination);

Parameters

varDestination
The variant destination.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

The default is output to string.

See Also

Create a DOMDocument Object from SAX Events | IMXWriter Interface | MXHTMLWriter Coclass

Applies to: MXXMLWriter Coclass


standalone Property

[This is preliminary documentation and subject to change.]

Sets the value of the standalone attribute in the XML declaration to "yes" or "no". If set to True, the XML declaration appears as the following in XML output:

<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
[Visual Basic]

Usage Syntax

oMXXMLWriter.standalone = boolValue
boolValue = oMXXMLWriter.standalone

Remarks

Boolean. Read/write. The default value is False. The standalone declaration indicates if a document relies on information from an external source, such as external document type definition (DTD), for its content.

If set to False, the XML parser will accept external resources, if there are any, without reporting an error. If set to True, the parser reports an error if the document references an external DTD or external entities.

Example

The following example reads books.xml and writes the value of the standalone attribute to "yes" in the XML declaration.

Dim rdr As New MSXML2.SAXXMLReader
Dim cnth As IVBSAXContentHandler
Dim wrt As New MXXMLWriter
wrt.indent = True
wrt.standalone = True
Set cnth = wrt
Set rdr.contentHandler = cnth
rdr.parseURL ("books.xml")
MsgBox wrt.output
[C/C++]

Syntax

[propput]
HRESULT standalone (
  [in] VARIANT_BOOL fValue);

[propget]
HRESULT standalone (
  [out, retval] VARIANT_BOOL * fValue);

Parameters

fValue
A Boolean expression (True/False) specifying whether the feature is on or off.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

Value | Description
True | The value of standalone is set to "yes".
False (default) | The value of standalone is set to "no".

See Also

Applies to: MXXMLWriter Coclass


version Property

[This is preliminary documentation and subject to change.]

Specifies the version to include in the XML declaration. The version property value defaults to "1.0". As of this writing, there have been no plans for any other version of the XML specification. However, if another version is created in the future, the version number in the XML specification will be used to identify which version of the specification the document supports.

[Visual Basic]

Usage Syntax

oMXXMLWriter.version = strVersion
strVersion = oMXXMLWriter.version
[C/C++]

Syntax

[propput]
HRESULT version (
  [in] BSTR strVersion);
[propget]
HRESULT version (
  [out, retval] BSTR * strVersion);

Parameters

strVersion
The BSTR of version.

Return Values

S_OK
The value returned if no errors are reported.

Remarks

Read/write. A string representing the version. The default value is "1.0".

See Also

Applies to: MXXMLWriter Coclass


ISAXAttributes Interface

The ISAXAttributes/IVBSAXAttributes interface allows access to a list of attributes by:

  • attribute index
  • namespace-qualified name
  • qualified (prefixed) name

Attributes that are declared #IMPLIED, but not specified in the start tag, are not in the list. In addition, attributes used as namespace declarations (xmlns*) are not in the list unless the "http://xml.org/sax/features/namespace-prefixes" feature is set to True. (It is False by default.)

If the namespace-prefixes feature is False, access by qualified name (QName) may not be available.

If the "http://xml.org/sax/features/namespaces" feature is False, access by namespace-qualified names may not be available.

Note Information provided during an event call is valid only during the invocation of that event. This applies to both strings and interfaces. Performance would decrease significantly otherwise.

Methods

getIndexFromName | Finds an attribute by name and returns the (zero-based) index for the attribute.
getIndexFromQName | Finds an attribute by XML 1.0 qualified name and returns the (zero-based) index for the attribute.
getLocalName | Finds an attribute's local name by index.
getQName | Finds an attribute's qualified name (QName) by index.
getType | Finds an attribute by index and returns the attribute's type, as declared in the document type definition (DTD) or schema.
getTypeFromName | Finds an attribute by namespace name and returns the attribute's type, as declared in the DTD or schema.
getTypeFromQName | Finds an attribute by XML 1.0 qualified name and returns the attribute's type, as declared in the DTD or schema.
getURI | Finds an attribute's namespace URI by index.
getValue | Returns the text value of an attribute.
getValueFromName | Finds the attribute by namespace name and returns the attribute's text value.
getValueFromQName | Finds the attribute by XML 1.0 qualified name and returns the attribute's text value.

[Visual Basic]

The IVBSAXAttributes interface is implemented by the Simple API for XML (SAX) reader.

Property

In addition to the preceding methods, the following property also applies to the IVBSAXAttributes interface.

length Returns the count of attributes for an element.

[C/C++]

Methods

In addition to the preceding methods, the following methods also apply to the ISAXAttributes interface.

getLength | Returns the count of attributes.
getName | Returns all information related to the name of an attribute at a given index.

Requirements

Implementation: msxml4.dll

[C/C++]

Header and LIB files: msxml2.h, msxml2.lib


getIndexFromName Method

Finds an attribute by name and returns the (zero-based) index for the attribute. For ambiguous names, this method returns the name from the first namespace.

[Visual Basic]

Implementation Syntax

Function getIndexFromName(ByVal strURI As String, ByVal strLocalName As _
String) As Long

Usage Syntax

StrVal = oIVBSAXAttributes.getIndexFromName(strURI, strLocalName)

Parameters

strURI
The namespace URI or, if the name has no namespace URI, an empty string.
strLocalName
The attribute's local name.

Return Values

If failed, raises a trappable error.

[C/C++]

Syntax

HRESULT getIndexFromName(
   [in] const wchar_t * pwchUri,
   [in] int cchUri,
   [in] const wchar_t * pwchLocalName,
   [in] int cchLocalName
   [out, retval] int * pnIndex);

Parameters

pwchUri [in]
The namespace URI or, if the name has no namespace URI, an empty string.
cchUri [in]
The length of the namespace URI string.
pwchLocalName[in]
The attribute's local name.
cchLocalName [in]
The length of the local name string.
pnIndex[out, retval]
The returned index value.

Return Values

S_OK
The value returned if the index value is returned successfully.
E_INVALIDARG
The value returned if no matching attribute is found.
E_FAIL
The value returned if an internal error occurs.

See Also

getIndexFromQName Method | getLength Method (C/C++) | length Property (Visual Basic)

Applies to: ISAXAttributes/IVBSAXAttributes Interface


getIndexFromQName Method

Finds an attribute by XML 1.0 qualified name (QName) and returns the (zero-based) index for the attribute. For ambiguous names, this method returns the name from the first namespace.

[Visual Basic]

Implementation Syntax

Function getIndexFromQName(ByVal strQName As String) As Long

Usage Syntax

StrVal= oIVBSAXAttributes.getIndexFromQName(strQName)

Parameters

strQName
The qualified name for the attribute.

Return Values

If failed, raises a trappable error.

[C/C++]

Syntax

HRESULT getIndexFromQName(
   [in] const wchar_t * pwchQName,
   [in] int cchQName,
   [out, retval] int * pnIndex);

Parameters

pwchQName [in]
The qualified name for the attribute.
cchQName[in]
The length of the qualified name string.
pnIndex[out, retval]
The returned index value.

Return Values

S_OK
The value returned if the index value is returned successfully.
E_INVALIDARG
The value returned if no matching attribute is found.
E_FAIL
The value returned if an internal error occurs.

See Also

getLength Method (C/C++) | length Property (Visual Basic)

Applies to: ISAXAttributes/IVBSAXAttributes Interface


getLength Method (C/C++)

Returns the count of attributes. After you know the number, you can iterate through the list of attributes.

Syntax

HRESULT getLength(
   [out, retval] int * pnLength);

Parameters

pnLength [out, retval]
The count of attributes in a list.

Return Values

S_OK
The value returned if the count is returned successfully.
E_FAIL
The value returned if an internal error occurs.

See Also

getURI Method | getLocalName Method | getQName Method | getName Method (C/C++) | getValue Method | getValueFromName Method | getValueFromQName Method

Applies to: ISAXAttributes Interface


getLocalName Method

Finds an attribute's local name by index. For "xmlns", this value is empty.

[Visual Basic]

Implementation Syntax

Function getLocalName(ByVal nIndex As Long) As String

Usage Syntax

StrVal = oIVBSAXAttributes.getLocalName(nIndex)

Parameters

nIndex
The attribute's index value.

Return Values

If failed, raises a trappable error.

[C/C++]

Syntax

HRESULT getLocalName(
   [in] int nIndex,
   [out] const wchar_t ** ppwchLocalName,
   [out] int * pcchLocalName);

Parameters

nIndex [in]
The attribute's index value.
ppwchLocalName [out]
The attribute's local name.
pcchLocalName [out]
The length of the local name string.

Return Values

S_OK
The value returned if the local name is returned successfully.
E_FAIL
The value returned if an internal error occurs.
E_INVALIDARG
The value returned if the local name cannot be found.

See Also

getLength Method (C/C++) | length Property (Visual Basic)

Applies to: ISAXAttributes/IVBSAXAttributes Interface


getName Method (C/C++)

Returns all information related to the name of an attribute at a given index. Each return string can be disabled by passing Null in for the text out parameter.

Syntax

HRESULT getName(
   [in] int nIndex,
   [out] const wchar_t ** ppwchUri,
   [out] int * pcchUri)
   [out] const wchar_t ** ppwchLocalName,
   [out] int * pcchLocalName,
   [out] const wchar_t ** ppwchQName,
   [out] int * pcchQName);

Parameters

nIndex [in]
The attribute's index value.
ppwchUri [out]
The attribute's URI.
pcchUri [out]
The length of the URI string.
ppwchLocalName [out]
The attribute's local name.
pcchLocalName [out]
The length of the local name string.
ppwchQName [out]
The qualified prefixed name of the attribute.
pcchQName [out]
The length of the qualified name string.

Return Values

S_OK
The value returned if successful.
E_FAIL
The value returned if an internal error occurs.
E_INVALIDARG
The value returned if an invalid index is provided.

See Also

getLength Method (C/C++)

Applies to: ISAXAttributes Interface


getQName Method

Finds an attribute's qualified name (QName) by index. For the "xmlns" namespace, the qname value is empty.

[Visual Basic]

Implementation Syntax

Function getQName(ByVal nIndex As Long) As String

Usage Syntax

StrVal = oIVBSAXAttributes.GetQName(nIndex)

Parameters

nIndex
The attribute's index value.

Return Values

If failed, raises a trappable error.

[C/C++]

Syntax

HRESULT getQName(
   [in] int nIndex,
   [out] const wchar_t ** ppwchQName,
   [out] int * ppchQName);

Parameters

nIndex [in]
The attribute's index value.
ppwchQName [out]
The attribute's qualified name.
ppchQName [out]
The length of the qualified name string or –1 (if zero-terminated).

Return Values

S_OK
The value returned if the QName is returned successfully.
E_FAIL
The value returned if an internal error is reported.
E_INVALIDARG
The value returned if QName is not found.

See Also

getLength Method (C/C++) | length Property (Visual Basic)

Applies to: ISAXAttributes/IVBSAXAttributes Interface


getType Method

Finds an attribute by index and returns the attribute's type, as declared in the document type definition (DTD) or schema. If there is no DTD or schema or the schema does not map directly to a DTD attribute type, the return value is "CDATA". For ambiguous names, the type from the first namespace is returned.

[Visual Basic]

Implementation Syntax

Function getType(ByVal nIndex As Long) As String

Usage Syntax

StrVal = oIVBSAXAttributes.getType(nIndex)

Parameters

nIndex
The attribute's index value.

Return Values

If the type is unknown, returns "CDATA".

If failed, raises a trappable error.

[C/C++]

Syntax

HRESULT getType(
   [in] int nIndex,
   [out] const wchar_t ** ppwchType
   [out] int * pcchType);

Parameters

nIndex [in]
The attribute's index value.
ppwchType [out]
The returned type of the attribute.
pcchType [out]
The length of the returned type attribute string.

Return Values

S_OK
The value returned if the attribute type is returned successfully.
E_INVALIDARG
The value returned for an invalid index or if no matching attribute is found.
E_FAIL
The value returned if an internal error occurs.

Remarks

The returned attribute type can be (but is not limited to) one of the following: CDATA, ID, IDREF, IDREFS, NMTOKEN, NMTOKENS, ENTITY, ENTITIES.

See Also

getTypeFromName Method | getTypeFromQName Method

Applies to: ISAXAttributes/IVBSAXAttributes Interface


getTypeFromName Method

Finds an attribute by namespace name and returns the attribute's type, as declared in the document type definition (DTD) or schema. If a DTD or schema does not exist or the schema type does not map directly to a DTD attribute type, the return value is "CDATA".

[Visual Basic]

Implementation Syntax

Function getTypeFromName(ByVal strURI As String, ByVal strLocalName As _
String) As String

Usage Syntax

StrVal = oIVBSAXAttributes.getTypeFromName(strURI,strLocalName)

Parameters

strURI
The namespace URI or, if the namespace has no URI, an empty string.
strLocalName
The local name of the attribute.

Return Values

If the type is unknown, returns CDATA.

[C/C++]

Syntax

HRESULT getTypeFromName(
   [in] const wchar_t * pwchUri,
   [in] int cchUri,
   [in] const wchar_t * pwchLocalName,
   [in] int cchLocalName,
   [out] const wchar_t ** ppwchType,
   [out] int * pcchType);

Parameters

pwchUri [in]
The namespace URI or, if the namespace has no URI, an empty string.
cchUri [in]
The length of the namespace URI string.
pwchLocalName [in]
The local name of the attribute.
cchLocalName [in]
The length of the local name string.
ppwchType [out]
The returned type of the attribute.
pcchType [out]
The length of the attribute-type string.

Return Values

S_OK
The value returned if the attribute type is returned successfully.
E_INVALIDARG
The value returned if an invalid index or no matching attribute is found.
E_FAIL
The value returned if an internal error is reported.

Remarks

The returned attribute type can be (but is not limited to) one of the following: CDATA, ID, IDREF, IDREFS, NMTOKEN, NMTOKENS, ENTITY, ENTITIES.

See Also

getType Method | getTypeFromName Method

Applies to: ISAXAttributes/IVBSAXAttributes Interface


getTypeFromQName Method

Finds an attribute by XML 1.0 qualified name (QName) and returns the attribute's type, as declared in the document type definition (DTD) or schema. If a DTD or schema does not exist or the schema type does not map directly to a DTD attribute type, the return value is "CDATA".

[Visual Basic]

Implementation Syntax

Function getTypeFromQName(ByVal strQName As String) As String

Usage Syntax

StrVal = oIVBSAXAttributes.getTypeFromQName(strQName)

Parameters

strQName
The qualified name.

Return Values

If the type is unknown, returns CDATA.

[C/C++]

Syntax

HRESULT getTypeFromQName(
   [in] const wchar_t * pwchQName,
   [in] int cchQName,
   [out] const wchar_t ** ppwchType,
   [out] int * pcchType);

Parameters

pwchQName [in]
The qualified name.
cchQName [in]
The length of the qualified name string.
ppwchType [out]
The returned type of the attribute.
pcchType [out]
The length of the attribute-type string.

Return Values

S_OK
The value returned if the attribute type is returned successfully.
E_INVALIDARG
The value returned for an invalid index or if no matching attribute is found.
E_FAIL
The value returned if an internal error occurs.

Remarks

The returned attribute type can be (but is not limited to) one of the following: CDATA, ID, IDREF, IDREFS, NMTOKEN, NMTOKENS, ENTITY, ENTITIES.

See Also

getType Method

Applies to: ISAXAttributes/IVBSAXAttributes Interface


getURI Method

Finds an attribute's namespace URI by index.

[Visual Basic]

Implementation Syntax

Function getURI(ByVal nIndex As Long) As String

Usage Syntax

StrVal = oIVBSAXAttributes.getURI(nIndex)

Parameters

nIndex
The attribute's index (zero-based).

Return Values

If a namespace URI is not available, returns an empty string

If the index is out of range, returns a trappable error message.

[C/C++]

Returns all the information related to the name of the attribute available at the index. Each return string can be disabled by passing Null in for the text out parameter. It is an error to pass Null for the character count unless Null is also passed for the corresponding text out parameter.

Syntax

HRESULT getURI(
   [in] int nIndex,
   [out] const wchar_t ** ppwchUri,
   [out] int * pcchUri);

Parameters

nIndex [in]
The attribute's index (zero-based).
ppwchUri [out]
The namespace URI.
pcchUri [out]
The length of the namespace URI.

Return Values

S_OK
The value returned if the URI is returned successfully.
E_INVALIDARG
The value returned for an invalid index or if no matching attribute is found.
E_FAIL
The value returned if an internal error occurs.

See Also

getLength Method (C/C++) | length Property (Visual Basic)

Applies to: ISAXAttributes/IVBSAXAttributes Interface


getValue Method

Returns the text value of the attribute.

[Visual Basic]

If the index is out of range, this method returns a trappable error.

Implementation Syntax

Function getValue(ByVal nIndex As Long) As String

Usage Syntax

StrVal = oIVBSAXAttributes.getValue(nIndex)

Parameters

nIndex
The attribute index (zero-based).

Return Values

If failed, raises a trappable error if the index is out of range.

[C/C++]

If the index is out of range, this method returns a Null value.

Syntax

HRESULT getValue(
   [in] int nIndex,
   [out] const wchar_t ** ppwchValue,
   [out] int * pcchValue);

Parameters

nIndex [in]
The attribute index (zero-based).
ppwchValue [out]
The string value of the attribute.
pcchValue [out]
The length of the attribute string.

Return Values

S_OK
The value returned if the text value is returned successfully.
E_INVALIDARG
The value returned if an invalid index or no matching attribute is reported.
E_FAIL
The value returned if an internal error occurs.

See Also

getLength Method (C/C++) | length Property (Visual Basic)

Applies to: ISAXAttributes/IVBSAXAttributes Interface


getValueFromName Method

Finds the attribute by namespace name and returns the attribute's text value. For ambiguous names, this method returns the value from the first namespace.

[Visual Basic]

Implementation Syntax

Function getValueFromName(ByVal strURI As String,_
  ByVal strLocalName As String) As String

Usage Syntax

StrVal = oIVBSAXAttributes.getValueFromName(strURI,strLocalName)

Parameters

strURI
The namespace URI or, if the name has no namespace URI, an empty string.
strLocalName
The local name of the attribute.

Return Values

If failed, raises a trappable error.

[C/C++]

Syntax

HRESULT getValueFromName(
   [in] const wchar_t * pwchUri,
   [in] int cchUri,
   [in] const wchar_t * pwchLocalName,
   [in] int cchLocalName,
   [out] const wchar_t ** ppwchValue,
   [out] int * pcchValue);

Parameters

pwchUri [in]
The namespace URI or, if the namespace has no URI, an empty string.
cchUri [in]
The length of the URI string.
pwchLocalName [in]
The local name of the attribute.
cchLocalName [in]
The length of the local name string.
ppwchValue [out]
The string value of the attribute.
pcchValue [out]
The length of the attribute's string value.

Return Values

S_OK
The value returned if the text value is returned successfully.
E_INVALIDARG
The value returned for an invalid index or if no matching attribute is reported.
E_FAIL
The value returned if an internal error occurs.

See Also

getLength Method (C/C++) | length Property (Visual Basic)

Applies to: ISAXAttributes/IVBSAXAttributes Interface


getValueFromQName Method

Finds the attribute by XML 1.0 qualified name and returns the attribute's text value.

[Visual Basic]

Implementation Syntax

Function getValueFromQName(ByVal strQName As String) As String

Usage Syntax

StrValue = oIVBSAXAttributes.getValueFromQName(strQName)

Parameters

strQName
The XML 1.0 qualified name.

Return Values

If failed, raises a trappable error.

[C/C++]

Syntax

HRESULT getValueFromQName(
   [in] const wchar_t * pwchQName,
   [in] int cchQName,
   [out] const wchar_t ** pwchValue,
   [out] int * pcchValue);

Parameters

pwchQName [in]
The XML 1.0 qualified name.
cchQName [in]
The length of the qualified name string.
pwchValue [out]
The string value of the qualified name.
pcchValue [out]
The length of the qualified name.

Return Values

S_OK
The value returned if the text value is returned successfully.
E_INVALIDARG
The value returned d for an invalid index or if no matching attribute is found.
E_FAIL
The value returned if an internal error occurs.

See Also

getLength Method (C/C++) | length Property (Visual Basic)

Applies to: ISAXAttributes/IVBSAXAttributes Interface


length Property (Visual Basic)

Returns the count of attributes for an element. After you know the number, you can iterate through the list of attributes.

Implementation Syntax

Property Get IVBSAXAttributes_length() As Long

Usage Syntax

StrVal = oIVBSAXAttributes.length

Parameters

length
The count of attributes in a list.

Return Values

If there are no attributes in the collection, returns a "0".

If failed, raises a trappable error.

See Also

getURI Method | getLocalName Method | getValue Method | getValueFromName Method | getValueFromQName Method

Applies to: IVBSAXAttributes Interface


ISAXContentHandler Interface

The ISAXContentHandler/IVBSAXContentHandler interface receives notification of the logical content of a document. This is the main interface implemented by most Simple API for XML (SAX) applications.

Note Only one ContentHandler can be registered at a time.

Methods

characters | Receives notification of character data.
endDocument | Receives notification of the end of a document.
startDocument | Receives notification of the beginning of a document.
endElement | Receives notification of the end of an element.
startElement | Receives notification of the beginning of an element.
ignorableWhitespace | Receives notification of ignorable white space in element content. This method is not called in the current implementation because the SAX2 implementation is nonvalidating.
endPrefixMapping | Ends the scope of a prefix-URI namespace mapping.
startPrefixMapping | Begins the scope of a prefix-URI namespace mapping.
processingInstruction | Receives notification of a processing instruction.
skippedEntity | Receives notification of a skipped entity.

[Visual Basic]

If the application must be informed of basic parsing events, it implements this interface and registers an instance with the XML Reader using the contentHandler property. The reader then calls the methods of the ContentHandler, such as the start of element, the end of elements, and character data.

This interface handles events passed by the SAXXMLReader. The order of events handled by IVBSAXContentHandler follows the order of the information within the document being parsed. For example, the IVBSAXContentHandler interface handles all of an element's content, including character data, processing instructions, and subelements, in order after first handling the startElement event and before handling the endElement event.

The interface includes a series of methods that the reader invokes during the parsing operation. The reader passes the appropriate information to the method's parameters. To perform processing for a method, you simply add code to the method in the ContentHandler implementation. In general, it's rare that you would call these methods yourself from within the ContentHandler. As such, the syntax shown for the IVBSAXContentHandler interface focuses on the implementation syntax, rather than usage syntax.

Important The SAX2 reader passes string values to IVBSAXContentHandler methods by reference, rather than value.

Properties

In addition to the preceding methods, the following property also applies to the IVBSAXContentHandler interface.

documentLocator Receives an interface pointer to the IVBSAXLocator interface, which provides methods for returning the column number, line number, public ID, or system ID for a current document event.

[C/C++]

If the application must be informed of basic parsing events, it implements this interface and registers an instance with the XML Reader using the putContentHandler method. The reader then uses this instance to report basic document-related events, such as the start of elements, the end of elements, and character data.

This interface handles events passed by the SAXXMLReader. The order of events handled by ISAXContentHandler follows the order of the information within the document being parsed. For example, after handling the startElement event and before handling the endElement event, the ISAXContentHandler interface handles all of an element's content, including character data, processing instructions, and subelements.

Methods

In addition to the preceding methods, the following method also applies to the ISAXContentHandler interface.

characters | Receives notification of character data.
endDocument | Receives notification of the end of a document.
startDocument | Receives notification of the beginning of a document.
endElement | Receives notification of the end of an element.
startElement | Receives notification of the beginning of an element.
ignorableWhitespace | Receives notification of ignorable white space in element content. This method is not called in the current implementation because the SAX2 implementation is nonvalidating.
endPrefixMapping | Ends the scope of a prefix-URI namespace mapping.
startPrefixMapping | Begins the scope of a prefix-URI namespace mapping.
processingInstruction | Receives notification of a processing instruction.
putDocumentLocator | Receives an interface for locating the origin of SAX document events.
skippedEntity | Receives notification of a skipped entity.

Requirements

Implementation: msxml4.dll

[C/C++]

Header and LIB files: msxml2.h, msxml2.lib

See Also

contentHandler Property (Visual Basic) | putContentHandler Method (C/C++) | IVBSAXLocator Interface


characters Method

Receives notification of character data.

[Visual Basic]

The reader calls the characters method and passes it character data. The reader can pass all contiguous character data in a single chunk or split it into several chunks. All characters in a single event, however, must come from the same external entity, so that the Locator object provides useful information. The ContentHandler must not attempt to read from the array outside the specified range. The reader calls the character method between the startElement and endElement methods. The reader passes strings to the characters method by reference (ByRef), not by name (ByVal). This improves performance and avoids extra string copying.

Implementation Syntax

Sub characters(strChars As String)

Parameters

strChars
The character data.

Return Values

If failed, the ContentHandler raises a trappable error.

[C/C++]

Receives notification of character data. The reader calls the characters method to report each chunk of character data. The reader can return all contiguous character data in a single chunk or split it into several chunks. All characters in a single event, however, must come from the same external entity so that the Locator object can provide useful information. The application must not attempt to read from the array outside the specified range.

Syntax

HRESULT characters(
   [in] const wchar_t * pwchChars,
   [in] int cchChars);

Parameters

pwchChars [in]
The character data.
cchChars [in]
The length of the character string.

Return Values

S_OK
The value returned if the character data is returned successfully.
E_FAIL
The value returned if an internal error occurs.

Remarks

The characters method does not convert CR-LF("\r\n") to the Java LF('\n') implementation.

See Also

Applies to: ISAXContentHandler/IVBSAXContentHandler Interface


endDocument Method

Receives notification of the end of a document. The reader invokes the endDocument method only once—at the end of the document. The endDocument method is the last method invoked during the parse. The reader does not invoke this method until it has either abandoned parsing upon encountering an unrecoverable error or has reached the end of the document.

[Visual Basic]

Implementation Syntax

Sub endDocument()

Return Values

If failed, the ContentHandler may raise an exception, any Simple API for XML (SAX) exception, possibly wrapping another exception.

[C/C++]

Syntax

HRESULT endDocument();

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

startDocument Method

Applies to: ISAXContentHandler/IVBSAXContentHandler Interface


startDocument Method

Receives notification of the beginning of a document. The reader invokes the startDocument method only once.

[Visual Basic]

It is invoked before any other methods in the IVBSAXContentHandler interface or in the IVBSAXDTDHandler interface, with the exception of the documentLocator property.

Implementation Syntax

Sub startDocument()

Return Values

If failed, the ContentHandler raises a trappable error.

[C/C++]

It is invoked before any other methods in the ISAXContentHandler interface or in the ISAXDTDHandler interface, with the exception of the putDocumentLocator method.

Syntax

HRESULT startDocument();

Return Values

S_OK
The value returned if successful.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

documentLocator Property (Visual Basic) | endDocument Method | ISAXDTDHandler Interface | putDocumentLocator Method (C/C++)

Applies to: ISAXContentHandler/IVBSAXContentHandler Interface


endElement Method

Receives notification of the end of an element. The reader invokes this method at the end of every element in the XML document.

[Visual Basic]

A corresponding startElement method is invoked for every endElement method, even when the element is empty.

Implementation Syntax

Sub endElement(strNamespaceURI As String, strLocalName As_
String, strQName As String)

Parameters

strNamespaceURI
The namespace URI or an empty string (if the element has no namespace URI or if namespace processing is not being performed).
strLocalName
The local name (without prefix) or an empty string (if namespace processing is not being performed).
strQName
The QName—XML 1.0 qualified name (with prefix)—or an empty string (if the QName is not available).

Return Values

If failed, the ContentHandler raises a trappable error.

Remarks

This method allows up to three names for each element:

  • the namespace URI
  • the local name
  • the QName, if available

Any or all of these name components may be specified, depending on the values of the "http://xml.org/sax/features/namespaces" and the "http://xml.org/sax/features/namespace-prefixes" features. The namespace URI and local name are required when the "http://xml.org/sax/features/namespaces" feature is True (the default). These values are optional when this feature is set to False. Note that neither the URI nor the local name value can be specified on its own. Both values are required.

[C/C++]

A corresponding startElement event occurs for every endElement event, even when the element is empty.

This event allows up to three name components for each element:

  • the namespace URI
  • the local name
  • QName—the qualified XML 1.0 name (with prefix)—or an empty string if the QName is not available

Any or all of these name components may be provided, depending on the values of the "http://xml.org/sax/features/namespaces" and the "http://xml.org/sax/features/namespace-prefixes" features. The namespace URI and local name are required when the "http://xml.org/sax/features/namespaces" feature is True (the default). These values are optional when this feature is set to False. Note that neither the URI nor the local name value can be specified on its own. Both values are required.

Syntax

HRESULT endElement(
   [in] const wchar_t * pwchNamespaceUri,
   [in] int cchNamespaceUri,
   [in] const wchar_t * pwchLocalName,
   [in] int cchLocalName
   [in] const wchar_t * pwchQName
   [in] int cchQName);

Parameters

pwchNamespaceUri [in]
The namespace URI.
cchNamespaceUri [in]
The length for the namespace URI string.
pwchLocalName [in]
The local name string.
cchLocalName [in]
The length of the local name string.
pwchQName [in]
The QName (with prefix) or, if QNames are not available, an empty string.
cchQName [in]
The length of the QName string.

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

startElement Method

Applies to: ISAXContentHandler/IVBSAXContentHandler Interface


startElement Method

Receives notification of the beginning of an element. The reader invokes the startElement method at the beginning of every element in the XML document.

[Visual Basic]

A corresponding endElement method is called for every startElement method, even when the element is empty.

Implementation Syntax

Sub startElement(strNamespaceURI As String, strLocalName As String,_
strQName As String, oAttributes As IVBSAXAttributes)

Parameters

strNamespaceURI
The namespace URI.
strLocalName
The local name string.
strQName
The QName—XML 1.0 qualified name (with prefix)—or an empty string (if raw names are not available).
oAttributes
The attributes attached to the element.

Return Values

If failed, the ContentHandler raises a trappable error.

Remarks

This method allows up to three names for each element:

  • the namespace URI
  • the local name
  • the QName, if available

Any or all of the of these name components may be specified, depending on the values of the "http://xml.org/sax/features/namespaces" and the "http://xml.org/sax/features/namespace-prefixes" features. The namespace URI and local name are required when the "http://xml.org/sax/features/namespaces" feature is True (the default). These values are optional when this feature is set to False. Neither the URI nor local name value can be specified on its own. Both values are required if either is used.

The QName is required when the "http://xml.org/sax/features/namespaces-prefixes feature" is True and is optional when this feature is False (the default).

The attribute list provided contains only attributes with explicit values (specified or default). The attribute list omits #IMPLIED attributes. Furthermore, the attribute list contains attributes used for namespace declarations (xmlns* attributes) only if the "http://xml.org/sax/features/namespace-prefixes" feature is True. This feature is False by default.

[C/C++]

A corresponding endElement method is called for every startElement event, even when the element is empty.

The startElement event allows up to three name components for each element:

  • the namespace URI
  • the local name
  • QName—the qualified XML 1.0 name

Any or all of these name components may be specified, depending on the values of the "http://xml.org/sax/features/namespaces" and the "http://xml.org/sax/features/namespace-prefixes" features. The namespace URI and local name are required when the "http://xml.org/sax/features/namespaces" feature is True (the default). These values are optional when this feature is set to False. Note that neither the URI nor local name value can be specified on its own. Both values are required if either is used.

The QName is required when the "http://xml.org/sax/features/namespaces-prefixes feature" is True and is optional when this feature is False (the default).

The attribute list provided contains only attributes with explicit values (specified or default). The attribute list omits #IMPLIED attributes. Furthermore, the attribute list contains attributes used for namespace declarations (xmlns* attributes) only if the "http://xml.org/sax/features/namespace-prefixes" feature is True. This feature is False by default.

Syntax

HRESULT startElement(
   [in] const wchar_t * pwchNamespaceUri,
   [in] int cchNamespaceUri,
   [in] const wchar_t * pwchLocalName,
   [in] int cchLocalName
   [in] const wchar_t * pwchQName
   [in] int cchQName);
   [in] ISAXAttributes * pAttributes);

Parameters

pwchNamespaceUri [in]
The namespace URI.
cchNamespaceUri [in]
The length for the namespace URI.
pwchLocalName [in]
The local name string.
cchLocalName [in]
The length of the local name.
pwchQName [in]
The QName (with prefix) or, if QNames are not available, an empty string.
cchQName [in]
The length of the QName.
pAttributes [in]
The attributes attached to the element.

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

endElement Method

Applies to: ISAXContentHandler/IVBSAXContentHandler Interface


ignorableWhitespace Method

This method is not called in the current implementation because the Simple API for XML (SAX2) implementation is nonvalidating.

[Visual Basic]

You can manually call the ignorableWhitespace method to pass white space characters such as space, carriage return, tab, or line feed to the internal buffer of the MXXMLWriter object.

Usage Syntax

oContentHandler.ignorableWhitespace(strChars As String)

Parameters

strChars
The character data.

Return Values

If failed, the ContentHandler raises a trappable error.

[C/C++]

You can manually call the ignorableWhitespace method to pass ignorable white space characters to MXXMLWriter.

Syntax

HRESULT ignorableWhitespace(
   [in] const wchar_t * pwchChars,
   [in] int cchChars);

Parameters

pwchChars [in]
The character data.
cchChars [in]
The length of the character string.

Return Values

S_OK
The value returned if the character data is returned successfully.
E_FAIL
The value returned if an internal error occurs.

Remarks

The ignorableWhitespace method does not convert CR-LF("\r\n") to the Java LF('\n') implementation.

See Also

Use MXXMLWriter

Applies to: ISAXContentHandler/IVBSAXContentHandler Interface


endPrefixMapping Method

Ends the scope of the prefix-URI namespace mapping.

[Visual Basic]

The reader calls this method after the corresponding endElement method.

Implementation Syntax

Sub endPrefixMapping(strPrefix As String)

Parameters

strPrefix
The prefix being mapped.

Return Values

If failed, the ContentHandler raises a trappable error.

[C/C++]

This event always occurs after the corresponding endElement event, but the order of the endPrefixMapping events is not otherwise guaranteed.

Syntax

HRESULT endPrefixMapping(
   [in] const wchar_t * pwchPrefix,
   [in] int cchPrefix);

Parameters

pwchPrefix [in]
The prefix being mapped.
cchPrefix [in]
The length of the prefix string.

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse operation should be aborted.

Remarks

The information from this event is not necessary for normal namespace processing. The reader automatically replaces prefixes for element and attribute names when the "http://xml.org/sax/features/namespaces" feature is True (the default).

There are cases, however, when applications need to use prefixes in character data or in attribute values, where they cannot safely be expanded automatically. In these contexts, the startPrefixMapping and endPrefixMapping methods can supply the information needed to expand prefixes..

There is no guarantee that the startPrefixMapping and endPrefixMapping events are properly nested relative to each other. All startPrefixMapping events occur before the corresponding startElement event and all endPrefixMapping events occur after the corresponding endElement event, but their order is not guaranteed.

See Also

endElement Method | startElement Method | startPrefixMapping Method

Applies to: ISAXContentHandler/IVBSAXContentHandler Interface


startPrefixMapping Method

Begins the scope of the prefix-URI namespace mapping.

[Visual Basic]

This method is always invoked after the corresponding endElement method.

Implementation Syntax

Sub startPrefixMapping(strPrefix As String, strURI As String)

Parameters

strPrefix
The namespace prefix being declared.
strURI
The namespace URI to which the prefix is mapped.

Return Values

If failed, the ContentHandler raises a trappable error.

[C/C++]

This method is always invoked after the corresponding endElement event, but the order of the endPrefixMapping events is not otherwise guaranteed.

Syntax

HRESULT startPrefixMapping(
   [in] const wchar_t * pwchPrefix,
   [in] int cchPrefix,
   [in] const wchar_t * pwchUri
   [in] int cchUri);

Parameters

pwchPrefix [in]
The prefix being mapped.
cchPrefix [in]
The length of the prefix string or –1 (if zero-terminated).
pwchUri [in]
The namespace URI to which the prefix is mapped.
cchUri [in]
The length of the namespace URI string.

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse operation should be aborted.

Remarks

The information from this event is not necessary for normal namespace processing. The reader automatically replaces prefixes for element and attribute names when the "http://xml.org/sax/features/namespaces" feature is True (the default).

There are cases, however, when applications need to use prefixes in character data or in attribute values, where they cannot safely be expanded automatically. In these contexts, the startPrefixMapping and endPrefixMapping methods can supply the information needed to expand prefixes.

There is no guarantee that the startPrefixMapping and endPrefixMapping events are properly nested relative to each other. All startPrefixMapping events occur before the corresponding startElement event and all endPrefixMapping events occur after the corresponding endElement event, but their order is not guaranteed.

See Also

endElement Method | endPrefixMapping Method | startElement Method

Applies to: ISAXContentHandler/IVBSAXContentHandler Interface


processingInstruction Method

Receives notification of a processing instruction. The reader invokes the processingInstruction method once for each processing instruction found. Processing instructions can occur before or after the main document element.

[Visual Basic]

Implementation Syntax

Sub processingInstruction(strTarget As String, strData As String)

Parameters

strTarget
The target for the processing instruction. The target is the first piece of the processing instruction. For example, xml - stylesheet is the target for the processing instruction, <?xml – stylesheet href="sample.css" type="text/css" title="Sample" ?>.
strData
The processing instruction data or Null (if none is supplied).

Return Values

If failed, the ContentHandler raises a trappable error.

[C/C++]

Syntax

HRESULT processingInstruction(
   [in] const wchar_t * pwchTarget,
   [in] int cchTarget,
   [in] const wchar_t * pwchData,
   [in] int cchData);

Parameters

pwchTarget [in]
The target for the processing instruction. The target is the first piece of the processing instruction. For example, xml - stylesheet is the target for the processing instruction, <?xml – stylesheet href="sample.css" type="text/css" title="Sample" ?>.
cchTarget [in]
The length of the target string.
pwchData [in]
The processing instruction data or Null (if none is supplied).
cchData [in]
The length of the processing instruction string.

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

Applies to: ISAXContentHandler/IVBSAXContentHandler Interface


putDocumentLocator Method (C/C++)

Receives an interface for locating the origin of Simple API for XML (SAX) document events. The reader supplies a locator to the application by invoking this method before invoking any other methods in the ISAXContentHandler interface. This locator allows the application to determine the end position of any document-related event, even if the parser is not reporting an error. Typically, the application uses this information for reporting its own errors (for example, if the character content does not match an application's business rules).

Syntax

HRESULT putDocumentLocator(
   [in] ISAXLocator * pLocator);

Parameters

pLocator [in]
The interface pointer to an instance of an implementation of the ISAXLocator interface.

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse operation should be aborted.

Remarks

The information returned by the Locator object can sometimes be insufficient for use with a search engine. The locator returns the correct information only during the invocation of events in this interface. The application should not attempt to use this method at any other time.

See Also

ISAXLocator Interface | startDocument Method

Applies to: ISAXContentHandler Interface


skippedEntity Method

Receives notification of a skipped entity. The skippedEntity method is invoked for each entity skipped. The reader may skip entities if they have not been seen in the declarations—for example, when an entity is declared in an external DTD subset. The reader may skip external entities, depending on the values of the "http://xml.org/sax/features/external-general-entities" and "http://xml.org/sax/features/external-parameter-entities" features.

The skippedEntity method is also called in the case of an external DTD declaration. For example:

<!DOCTYPE xyz SYSTEM "http://…">
[Visual Basic]

Implementation Syntax

Sub skippedEntity(strName As String)

Parameters

strName
The name of the skipped entity. If the entity is a parameter entity, the name begins with '%'.

Return Values

If failed, the ContentHandler raises a trappable error.

[C/C++]

Syntax

HRESULT skippedEntity(
   [in] const wchar_t * pwchName,
   [in] int cchName);

Parameters

pwchName [in]
The name of the skipped entity. If the entity is a parameter entity, the name begins with '%'.
cchName [in]
The number of characters in the pwchName string.

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

putFeature Method

Applies to: ISAXContentHandler/IVBSAXContentHandler Interface


documentLocator Property (Visual Basic)

Receives an interface pointer to the IVBSAXLocator interface, which provides methods for returning the column number, line number, public ID, or system ID for a current document event.

The reader supplies a Locator object to the application by invoking this property before invoking any other methods in the IVBSAXContentHandler interface. This locator allows the application to determine the end position of any document-related event, even if the parser is not reporting an error. Typically, the application uses this information for reporting its own errors (for example, if the character content does not match an application's business rules).

Implementation Syntax

Property documentLocator As IVBSAXLocator

Return Values

If failed, the ContentHandler raises a trappable error.

Remarks

The Locator object returns the correct information only during the invocation of events in this interface. The application should not attempt to use this method at any other time.

See Also

IVBSAXLocator Interface | startDocument Method

Applies to: IVBSAXContentHandler Interface


ISAXDeclHandler Interface

If you are using the DeclHandler together with a LexicalHandler, all of the events occur between the startDTD and the endDTD events.

To set the DeclHandler for a SAX2 reader, use the putProperty method with the property ID, "http://xml.org/sax/properties/declaration-handler".

Methods

attributeDecl | Receives/reports an attribute type declaration.
elementDecl | Receives/reports an element type declaration.
externalEntityDecl | Receives/reports a parsed external entity declaration.
internalEntityDecl | Receives/reports a parsed internal entity declaration.

[Visual Basic]

The IVBSAXDeclHandler interface enables a Simple API for XML (SAX2) application to implement an optional extension handler for receiving information about DTD declarations in an XML document. SAX2 readers are not required to support this handler, and this handler is not included in the core SAX2 distribution.

Data-related DTD declarations (unparsed entities and notations) are already reported through the IVBSAXDTDHandler interface.

The IVBSAXDeclHandler interface includes a series of methods that are invoked by the reader during the parsing operation. The reader passes the appropriate information to the method's parameters. To perform some type of processing for a method, you simply add code to the method in the DeclHandler implementation. In general, it's rare that you would call these methods yourself from within the DeclHandler. As such, the syntax shown for the IVBSAXDeclHandler interface focuses on the implementation syntax, rather than usage syntax.

Important The SAX2 reader passes string values to IVBSAXDeclHandler methods by reference, rather than by value.
[C/C++]

This is an optional extension handler for SAX2 to provide information about DTD declarations in an XML document. Data-related DTD declarations (unparsed entities and notations) are already reported through the ISAXDTDHandler interface.

The following code shows how to use the putProperty method with the property ID, http://xml.org/sax/properties/declaration-handler, to set the DeclHandler for a SAX2 reader.

... SAXXMLReader * r = ...
SAXDeclHandler * dh = new SAXDeclHandler();
r->putProperty("http://xml.org/sax/properties/declaration-handler", _variant_t(dh));

Requirements

Implementation: msxml4.dll

[C/C++]

Header and LIB files: msxml2.h, msxml2.lib

See Also

endDTD Method | ISAXDTDHandler/IVBSAXDTDHandler Interface | putProperty Method | startDTD Method


attributeDecl Method

Receives/reports an attribute type declaration. Only the first declaration for an attribute is reported.

[Visual Basic]

The attribute type is one of these three choices:

  • one of the following strings—"CDATA", "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", or "ENTITIES".
  • a parenthesized token group with the separator "|" and all white space removed.
  • 8the word "NOTATION", followed by a space, followed by a parenthesized token group with all white space removed.

Any parameter entities in the attribute value are expanded, but general entities are not.

Implementation Syntax

Sub attributeDecl(strElementName As String, strAttributeName As String,_
strType As String, strValueDefault As String, strValue As String)

Parameters

strElementName
The name of the associated element.
strAttributeName
The name of the attribute.
strType
A string representing the attribute type.
strValueDefault
A string representing the attribute default ("#IMPLIED", "#REQUIRED", or "#FIXED") or Null (if none of these applies).
strValue
A string representing the attribute's default value or Null (if there is none).

Return Values

If failed, the DeclHandler raises a trappable error.

[C/C++]

The attribute type can be either of these two choices:

  • one of the following strings—"CDATA", "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES", or "NOTATION".
  • a parenthesized token group with the separator "|" and all white space removed.

Syntax

HRESULT attributeDecl(
   [in] const wchar_t * pwchElementName,
   [in] int cchElementName,
   [in] const wchar_t * pwchAttributeName,
   [in] int cchAttributeName,
   [in] const wchar_t * pwchType,
   [in] int cchType,
   [in] const wchar_t * pwchValueDefault,
   [in] int cchValueDefault,
   [in] const wchar_t * pwchValue,
   [in] int cchValue);

Parameters

pwchElementName [in]
The name of the associated element.
cchElementName [in]
The length of the element's name string.
pwchAttributeName [in]
The name of the attribute.
cchAttributeName [in]
The length of the attribute's name string.
pwchType [in]
A string representing the attribute type.
cchType [in]
The length of the attribute-type string.
pwchValueDefault [in]
A string representing the attribute default ("#IMPLIED", "#REQUIRED" or "#FIXED") or Null (if none of these apply).
cchValueDefault [in]
The length of the attribute's default string.
pwchValue [in]
A string representing the attribute's default value or Null (if there is none).
cchValue [in]
The length of the attribute's default value.

Return Values

S_OK
The value returned if no errors are reported.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

Applies to: ISAXDeclHandler/IVBSAXDeclHandler Interface


elementDecl Method

Receives/reports an element type declaration. The content model consists of the string "EMPTY", the string "ANY", or a group of values in parentheses that is optionally followed by an occurrence indicator (for example, <!ELEMENT DOCUMENT (TITLE,AUTHOR+,SUMMARY*,NOTE?)>). The model is normalized so that all parameter entities are fully resolved, all white space is removed, and enclosing parentheses are included. Other normalization (such as removing redundant parentheses or simplifying occurrence indicators) depends on the parser.

[Visual Basic]

Implementation Syntax

Sub elementDecl(strName As String, strModel As String)

Parameters

strName
The element type name.
strModel
The content model as a normalized string.

Return Values

If failed, the DeclHandler raises a trappable error.

[C/C++]

Syntax

HRESULT elementDecl(
   [in] const wchar_t * pwchName,
   [in] int cchName,
   [in] const wchar_t * pwchModel,
   [in] int cchModel);

Parameters

pwchName [in]
The element type name.
cchName [in]
The length of the element type name.
pwchModel [in]
The content model as a normalized string.
cchModel [in]
The content model as a normalized string length.

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

attributeDecl Method

Applies to: ISAXDeclHandler/IVBSAXDeclHandler Interface


externalEntityDecl Method

Receives/reports a parsed external entity declaration. Only the effective (first) declaration for each entity is reported.

[Visual Basic]

Implementation Syntax

Sub externalEntityDecl(strName As String, strPublicId As String,_
strSystemId As String)

Parameters

strName
The name of the entity. If it is a parameter entity, the name begins with '%'.
strPublicId
The declared public identifier of the entity or Null (if none was declared).
strSystemId
The declared system identifier of the entity.

Return Values

If failed, the DeclHandler raises a trappable error.

[C/C++]

Syntax

HRESULT externalEntityDecl();
   [in] const wchar_t * pwchName,
   [in] int cchName,
   [in] const wchar_t * pwchPublicId,
   [in] int cchPublicId,
   [in] const wchar_t pwchSystemId,
   [in] int cchSystemId);

Parameters

pwchName [in]
The name of the entity. If it is a parameter entity, the name begins with a "%".
cchName [in]
The length of the entity's name string.
pwchPublicId [in]
The declared public identifier of the entity or Null (if none is declared).
cchPublicId [in]
The length of the public identifier string.
pwchSystemId [in]
The declared system identifier of the entity.
cchSystemId [in]
The length of the system identifier string.

Return Values

S_OK
The value returned if no errors reported.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

internalEntityDecl Method

Applies to: ISAXDeclHandler/IVBSAXDeclHandler Interface


internalEntityDecl Method

Receives/reports a parsed internal entity declaration. Only the effective (first) declaration for each entity is reported.

[Visual Basic]

All parameter entities in the value are expanded, but general entities are not.

Implementation Syntax

Sub internalEntityDecl(strName As String, strValue As String)

Parameters

strName
The name of the entity. If it is a parameter entity, the name begins with '%'.
strValue
The replacement text of the entity.

Return Values

If failed, the DeclHandler raises a trappable error.

[C/C++]

Syntax

HRESULT internalEntityDecl(
   [in] const wchar_t * pwchName,
   [in] int cchName,
   [in] const wchar_t * pwchValue,
   [in] int cchValue);

Parameters

pwchName [in]
The name of the entity. If it is a parameter entity, the name begins with a "%".
cchName [in]
The length of the entity's name string.
pwchValue [in]
The replacement text of the entity.
cchValue [in]
The length of the replacement text string.

Return Values

S_OK
The value returned if no errors reported.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

externalEntityDecl Method

Applies to: ISAXDeclHandler/IVBSAXDeclHandler Interface


ISAXDTDHandler Interface

The ISAXDTDHandler/IVBSAXDTDHandler interface receives notification of basic document type definition (DTD)-related events.

Methods

notationDecl | Receives notification of a notation declaration event.
unparsedEntityDecl | Receives notification of an unparsed entity declaration event.

[Visual Basic]

If a Simple API for XML (SAX) application requires information about notations and unparsed entities, the application implements this interface and registers an instance with the SAX2 reader using the dtdHandler property. This DTDHandler instance reports notation and unparsed entity declarations to the application.

The IVBSAXDTDHandler interface includes methods that are invoked by the reader during the parsing operation. The reader passes the appropriate information to the method's parameters. To perform some type of processing for a method, you simply add code to the method in the DTDHandler implementation. In general, it's rare that you would call these methods yourself from within the DTDHandler. As such, the syntax shown for the IVBSAXDTDHandler interface focuses on the implementation syntax, rather than usage syntax.

Important The SAX2 reader passes string values to IVBSAXDTDHandler methods by reference, rather than by value.
[C++]

If a Simple API for XML (SAX) application requires information about notations and unparsed entities, the application implements this interface and registers an instance with the SAX2 reader using the putDTDHandler method. The instance of the DTDHandler reports notation and unparsed entity declarations to the application.

Remarks

This interface includes only those DTD events that the XML recommendation requires processors to report: notation and unparsed entity declarations.

The reader can report these events in any order, regardless of the order in which the notations and unparsed entities were declared. However, all DTD events must be reported after the ContentHandler's startDocument event, and before the first startElement event.

It is up to the application to store the information for future use (perhaps in a hash table or object tree). If the application encounters attributes of type NOTATION, ENTITY, or ENTITIES, it can use the information that it obtained through this interface to find the entity or notation corresponding to the attribute value.

Requirements

Implementation: msxml4.dll

[C++]

Header and LIB files: msxml2.h, msxml2.lib

See Also

dtdHandler Property (Visual Basic) | putDTDHandler Method (C/C++) | startDocument Method | startElement Method


notationDecl Method

Receives notification of a notation declaration event.

[Visual Basic]

If necessary, the application can record the notation for later reference. At least one of the PublicId or SystemId values must be available. If a system entity is present and it is a URL, the reader must resolve it before passing it to the application through the notationDecl method. There is no guarantee that the notation declaration will be reported before any unparsed entities that use it.

Implementation Syntax

Sub notationDecl(strName As String, strPublicId As String,_
strSystemId As String)

Parameters

strName
The notation's name.
strPublicId
The notation's public identifier or Null (if none was given).
strSystemId
The notation's system identifier (required).

Return Value

If failed, the DTDHandler raises a trappable error.

[C/C++]

It is the responsibility of the application to record the notation for later reference. If a system identifier is present and it is a URL, the reader must resolve it fully before passing it to the application.

Syntax

HRESULT notationDecl(
   [in] const wchar_t * pwchName,
   [in] int cchName,
   [in] const wchar_t * pwchPublicId,
   [in] int cchPublicId
   [in] const wchar_t * pwchSystemId
   [in] int cchSystemId);

Parameters

pwchName [in]
The notation's name.
cchName [in]
The length of the notation.
pwchPublicId [in]
The notation's public identifier or Null (if none was given).
cchPublicId [in]
The length of the public identifier.
pwchSystemId [in]
The notation's system identifier or Null (if none was given).
cchSystemId [in]
The length of the system identifier.

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse should be aborted.

See Also

unparsedEntityDecl Method

Applies to: ISAXDTDHandler/IVBSAXDTDHandler Interface


unparsedEntityDecl Method

Receives notification of an unparsed entity declaration event. The notation name corresponds to a notation reported by the notationDecl method or event. It is up to the application to record the entity for later reference, if necessary. If the system identifier is a URL, the reader must resolve it before passing it to the application.

[Visual Basic]

Implementation Syntax

Sub unparsedEntityDecl(strName As String, strPublicId As String,_
strSystemId As String, strNotationName As String)

Parameters

strName
The unparsed entity's name.
strPublicId
The entity's public identifier or Null (if none was given).
strSystemId
The entity's system identifier (required).
strNotationName
The name of the associated notation.

Return Values

If failed, the DTDHandler raises a trappable error.

[C/C++]

Syntax

HRESULT unparsedEntityDecl(
   [in] const wchar_t * pwchName,
   [in] int cchName,
   [in] const wchar_t * pwchPublicId,
   [in] int cchPublicId
   [in] const wchar_t * pwchSystemId
   [in] int cchSystemId);
   [in] const wchar_t * pwchNotationName
   [in] int cchNotationName);

Parameters

pwchName [in]
The unparsed entity's name.
cchName [in]
The length of the entity.
pwchPublicId [in]
The entity's public identifier or Null (if none was given).
cchPublicId [in]
The length of the public identifier.
pwchSystemId [in]
The entity's system identifier (required).
cchSystemId [in]
The length of the system identifier.
pwchNotationName [in]
The name of the associated notation.
cchNotationName [in]
The length of the notation.

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse should be aborted.

See Also

notationDecl Method

Applies to: ISAXDTDHandler/IVBSAXDTDHandler Interface


ISAXEntityResolver Interface

The ISAXEntityResolver/IVBSAXEntityResolver interface implements a handler to the resolveEntity event that is not called in the current Microsoft® XML Parser (MSXML) Simple API for XML (SAX2) implementation because it does not resolve external entities. You cannot override the default behavior for resolving external entities.

Methods

resolveEntity Allows the parser to resolve external entities.

This method is not called in the current SAX2 implementation.

Requirements

Implementation: msxml4.dll

[C/C++]

Header and LIB files: msxml2.h, msxml2.lib

Other Resources Other Resources

XML Industry Portal


resolveEntity Method

Allows the parser to resolve external entities.

Note This method is not called in the current Simple API for XML (SAX2) implementation.
[Visual Basic]

Implementation Syntax

Function resolveEntity(strPublicId As String, strSystemId As String)

Parameters

strPublicId
The public identifier of the external entity being referenced or Null (if none was supplied).
strSystemId
The system identifier of the external entity being referenced.

The application can also use this interface to redirect system identifiers to local URIs or to look up replacements in a catalog (possibly by using the public identifier).

[C/C++]

Syntax

HRESULT resolveEntity(
   [in] const wchar_t * pwchPublicId,
   [in] const wchar_t * pwchSystemId,
   [out,retval] VARIANT * pvarInput);

Parameters

pwchPublicId [in]
The public identifier of the external entity being referenced or Null (if there is none).
pwchSystemId [in]
The system identifier of the external entity being referenced.
pvarInput [out, retval]
The returned text of the entity. Acceptable input types are the same as for the parse method.

Return Values

S_OK
The value returned if no errors are reported.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

parse Method | unparsedEntityDecl Method

Applies to: ISAXEntityResolver Interface

Other Resources Other Resources

XML Industry Portal


ISAXErrorHandler Interface

The ISAXErrorHandler/IVBSAXErrorHandler interface provides the basic interface for handling parsing errors.

Methods

error | Receives notification of a recoverable error. This method is not called in the current SAX2 implementation.
fatalError | Receives notification of a nonrecoverable error.
ignorableWarning | Receives notification of a warning. This method is not called in the current SAX2 implementation.

[Visual Basic]

To implement customized error handling, the application must implement this interface and then register an instance with the SAX2 reader, using the errorHandler property. The reader then reports all errors and warnings through this interface. If an application does not register an ErrorHandler, XML parsing errors are unreported and unexpected behavior can occur.

In the original Java SAX2 implementation, all methods in this interface have only one parameter: SAXParseException. However, because exceptions are handled differently in COM, SAXException and derived classes are not implemented. Instead, the single SAXParseException parameter is replaced with the following methods for SAX2.

Currently, all errors are fatal.

If an error occurs during the parse operation, the reader invokes the methods in the ErrorHandler class and passes the method the appropriate error information. In general, it's rare that you would call these methods yourself. As such, the syntax shown for the IVBSAXErrorHandler interface focuses on implementation syntax, rather than usage syntax.

Important The SAX2 reader passes string values to IVBSAXErrorHandler methods by reference, rather than by value.
[C/C++]

To implement customized error handling, the application must implement this interface and then register an instance with the SAX2 reader using the putErrorHandler method. The reader then reports all errors and warnings through this interface. If an application does not register an ErrorHandler, XML parsing errors are unreported and unexpected behavior can occur.

In the original Java SAX2 implementation, all methods in this interface have only one parameter: SAXParserException. However, because exceptions are handled differently in COM, SAXException and derived classes are not implemented. For this reason the single SAXParserException parameter is replaced with the following input parameters.

[in] ISAXLocator * pLocator
The Locator object, which contains line and column numbers of the error. SystemID and PublicID may be unavailable for particular data sources, such as character buffer.
[in] const wchar_t * pwchErrorMessage
The property inherited from the class, org.xml.sax.SAXException. In a COM implementation, provides error information.
[in] HRESULT hrErrorCode
The HRESULT code for the reason of the error.

All these methods can return either S_OK code (which matches the Java 'void xyz()' and still aborts parsing for fatal errors), or E_FAIL (which matches throwing a Java exception) and means that parsing should be aborted no matter what level.

Currently, all errors are fatal.

Requirements

Implementation: msxml4.dll

[C/C++]

Header and LIB files: msxml2.h, msxml2.lib

See Also

errorHandler Property (Visual Basic) | putErrorHandler Method (C/C++)


error Method

Receives notification of a recoverable error.

Note This method is not called in the current Simple API for XML (SAX2) implementation.
[Visual Basic]

Impementation Syntax

Sub error(oLocator As IVBSAXLocator, strError As String,_
nErrorCode As Long)

Parameters

oLocator
The Locator object, which contains line and column numbers of the error. SystemID and PublicID may be unavailable for particular data sources, such as character buffer.
strError
The error information.
nErrorCode
The error code.
[C/C++]

Syntax

HRESULT error(
   [in] ISAXLocator * pLocator,
   [in] const wchar_t * pwchErrorMessage
   [in] HRESULT hrErrorCode);

Parameters

pLocator [in]
The Locator object, which contains line and column numbers of the error. SystemID and PublicID may be unavailable for particular data sources, such as character buffer.
pwchErrorMessage [in]
The error information.
hrErrorCode [in]
The error code identifying the reason for the error.

Return Values

S_OK
The value returned when the error is handled and parsing may proceed.
Other
The value returned if parsing should be aborted.

See Also

errorHandler Property | putErrorHandler Method | ISAXLocator Interface

Applies to: ISAXErrorHandler/IVBSAXErrorHandler Interface


fatalError Method

Receives notification of a nonrecoverable error.

[Visual Basic]

Implementation Syntax

Sub fatalError(oLocator As IVBSAXLocator, strError As String,_
nErrorCode As Long)

Parameters

oLocator
The Locator object, which contains line and column numbers of the error. SystemID and PublicID may be unavailable for particular data sources, such as character buffer.
strError
The error information.
nErrorCode
The error code.

Remarks

This notification of a nonrecoverable error corresponds to the definition of a fatal error in section 1.2 of the Worldwide Web Consortium (W3C) XML 1.0 Recommendation. For example, a parser would use this method to report the violation of a well-formedness constraint. The application must assume that the document is unusable after the parser has invoked this method. Parsing should continue only to collect additional error messages. In addition, the parser is free to stop reporting any other events once this method has been invoked.

[C/C++]

Syntax

HRESULT fatalError(
   [in] ISAXLocator * pLocator,
   [in] const wchar_t * pwchErrorMessage,
   [in] HRESULT hrErrorCode);

Parameters

pLocator [in]
The Locator object, which contains line and column numbers of the error. SystemID and PublicID may be unavailable for particular data sources, such as character buffer.
pwchErrorMessage [in]
The error information.
hrErrorCode [in]
The error code identifying the reason for the error.

Return Values

S_OK
The value returned when the error is handled, but parsing stops for fatal errors.
Other
The value returned if parsing should be aborted.

See Also

errorHandler Property (Visual Basic) | putErrorHandler Method (C/C++) | ISAXLocator/IVBSAXLocator Interface

Applies to: ISAXErrorHandler/IVBSAXErrorHandler Interface


warning Method

Receives notification of a warning.

Note This method is not called in the current Simple API for XML (SAX2) implementation.
[Visual Basic]

Implementation Syntax

Sub ignorableWarning(oLocator As IVBSAXLocator, _
  strErrorMessage As String, nErrorCode As Long)

Parameters

oLocator
The Locator object, which contains line and column numbers of the error. SystemID and PublicID may be unavailable for particular data sources, such as character buffer.
strErrorMessage
The error information.
nErrorCode
The error code.

Remarks

The reader uses this method to report conditions that are not errors as defined by the XML 1.0 Recommendation. The default behavior is to take no action. The reader must continue to provide normal parsing events after invoking this method. It should still be possible for the application to process the document through to the end.

[C/C++]

Syntax

HRESULT ignorableWarning(
   [in] ISAXLocator * pLocator,
   [in] const wchar_t * pwchErrorMessage,
   [in] HRESULT hrErrorCode);

Parameters

pLocator [in]
The Locator object, which contains line and column numbers of the error. SystemID and PublicID may be unavailable for particular data sources, such as character buffer.
pwchErrorMessage [in]
The error information.
hrErrorCode [in]
The error code identifying the reason for the error.

Return Values

S_OK
The value returned when the error is handled and parsing may proceed.
Other
The value returned if parsing should be aborted.

See Also

errorHandler Property (Visual Basic) | putErrorHandler Method (C/C++) | ISAXLocator/IVBSAXLocator Interface

Applies to: ISAXErrorHandler/IVBSAXErrorHandler Interface


ISAXLexicalHandler Interface

The ISAXLexicalHandler/IVBSAXLexicalHandler interface enables a Simple API for XML (SAX2) application to implement an optional extension handler for receiving information from the SAX2 reader, such as comments, the document type declaration, CDATA sections, and the start and end of an entity within a document. The events in the LexicalHandler apply to the entire document, not just to the document elements. All LexicalHandler events must appear between the startDocument and endDocument events of the ContentHandler.

To set the LexicalHandler for the reader, use the putProperty method with the property ID "http://xml.org/sax/properties/lexical-handler".

Methods

comment | Receives XML comments from either inside or outside the document element, including comments in the external document type definition (DTD) or schema subset.
endCDATA | Receives the end of a character data (CDATA) section.
startCDATA | Receives the beginning of a CDATA section.
endDTD | Receives the end of a document type declaration.
startDTD | Receives the beginning of a document type declaration.
endEntity | Indicates that the reader has opened and finished processing an externally defined entity in the content of the document.
startEntity | Indicates that the reader has opened and started to process an internally or externally defined entity in the content of the document.

[Visual Basic]

The IVBSAXLexicalHandler interface includes a series of methods that are invoked by the reader during the parsing operation. The reader passes the appropriate information to the method's parameters. To perform processing for a method, you simply add code to the method in the LexicalHandler implementation. In general, it's rare that you would call these methods yourself from within the LexicalHandler. The syntax shown for the IVBSAXLexicalHandler interface focuses on implementation rather than usage.

Important The SAX2 reader passes string values to IVBSAXContentHandler methods by reference, rather than by value.
[C/C++]

The code to register the LexicalHandler may look like the following.

... SAXXMLReader * r = ...
SAXLexicalHandler * lh = new SAXLexicalHandler ();
r->putProperty("http://xml.org/sax/properties/lexical-handler",_variant_t(lh));

Requirements

Implementation: msxml4.dll

[C/C++]

Header and LIB files: msxml2.h, msxml2.lib

See Also

endDocument Method | putProperty Method | startDocument Method


comment Method

Receives XML comments from either inside or outside the document element, including comments in the external document type definition (DTD) or schema subset.

Comments in the DTD must be properly nested inside startDTD/endDTD and startEntity/endEntity events (if used).

[Visual Basic]

Implementation Syntax

Sub comment(strChars As String)

Parameters

strChars
The comment data.

Return Values

If failed, the LexicalHandler raises a trappable error.

[C/C++]

XML comments use the familiar HTML comment notation.

<!-- comments go here. -->

Syntax

HRESULT comment(
   [in] const wchar_t * pwchChars,
   [in] int cchChars);

Parameters

pwchChars [in]
The comment data.
cchChars [in]
The length of the comment string.

Return Values

S_OK
The value returned if the comment data is returned successfully.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

Applies to: ISAXLexicalHandler/IVBSAXLexicalHandler Interface


endCDATA Method

Receives the end of a character data (CDATA) section.

[Visual Basic]

Implementation Syntax

Sub endCDATA()

Return Values

If failed, the LexicalHandler raises a trappable error.

[C/C++]

The contents of the CDATA section are reported through the characters event. The endCDATA event reports only the end boundary of the CDATA section.

A CDATA section provides a way to include characters such as "<", ">", and "&" in an XML document that would normally interfere with processing. A CDATA section uses the following syntax:

<![CDATA[text goes here]]>.

Syntax

HRESULT endCDATA();

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

characters Method | startCDATA Method

Applies to: ISAXLexicalHandler/IVBSAXLexicalHandler Interface


startCDATA Method

Receives the beginning of a character data (CDATA) section. The contents of the CDATA section are reported through the regular characters event.

[Visual Basic]

This event is intended only to report the boundary.

Implementation Syntax

Sub startCDATA()

Return Values

If successful, returns void.

If failed, the application may raise an exception.

[C/C++]

The startCDATA event reports only the end boundary of the CDATA section.

A CDATA section provides a way to include characters such as "<", ">", and "&" in an XML document that would normally interfere with processing. A CDATA section uses the following syntax:

<![CDATA[text goes here]]>.

Syntax

HRESULT startCDATA();

Return Values

S_OK
The value returned if successful.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

characters Method | endCDATA Method

Applies to: ISAXLexicalHandler/IVBSAXLexicalHandler Interface


endDTD Method

Receives the end of a document type declaration. If the document has no such declaration, this method will not be invoked.

[Visual Basic]

Implementation Syntax

Sub endDTD()

Return Values

If failed, the LexicalHandler raises a trappable error.

[C/C++]

A document type declaration connects a document to its document type definition (DTD), which defines the rules of the document, such as what tags can go in your document, what tags can contain other tags, and the number and sequence of the tags. This declaration always begins with "<!DOCTYPE", followed by the name of the DTD, followed by a declaration of the DTD or a link to where the DTD can be found. Finally, it ends with a ">" to close the declaration. For example:

<!DOCTYPE NAME [
…DTD content goes here.
]>

Syntax

HRESULT endDTD();

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

startDTD Method

Applies to: ISAXLexicalHandler/IVBSAXLexicalHandler Interface


startDTD Method

Receives the beginning of a document type declaration. If the document has no such declaration, this method will not be invoked.

[Visual Basic]

All declarations reported through DTDHandler or DeclHandler events must appear between the startDTD and endDTD events. Declarations are assumed to belong to the internal document type definition (DTD) subset unless they appear between the startEntity and endEntity events. Comments and processing instructions from the DTD should also be reported between the startDTD and endDTD events.

Note The startDTD/endDTD events appear within the startDocument/endDocument events of the ContentHandler and before the first startElement event.

Implementation Syntax

Sub startDTD(strName As String, strPublicId As String, strSystemId As_
String)

Parameters

strName
The document type name.
strPublicId
The declared public identifier for the external DTD subset or Null (if none was declared).
strSystemId
The declared system identifier for the external DTD subset or Null (if none was declared).

Return Values

If failed, the LexicalHandler raises a trappable error.

[C/C++]
Note Any declarations are assumed to be in the internal subset unless otherwise indicated by a startEntity event.

The startDTD method is called within the startDocument and endDocument events from the ContentHandler and before the first startElement event.

A document type declaration connects a document to its document type definition (DTD), which defines the rules of the document, such as what tags can go in your document, what tags can contain other tags, and the number and sequence of the tags. This declaration always begins with "<!DOCTYPE", followed by the name of the DTD, followed by a declaration of the DTD or a link to where the DTD can be found. Finally, it ends with a ">" to close the declaration. For example:

<!DOCTYPE NAME [
…DTD content goes here.
]>

Syntax

HRESULT startDTD(
   [in] const wchar_t * pwchName,
   [in] int cchName,
   [in] const wchar_t * pwchPublicId,
   [in] int cchPublicId,
   [in] const wchar_t * pwchSystemId,
   [in] int cchSystemId);

Parameters

pwchName [in]
The document type name.
cchName [in]
The length of the document type's name.
pwchPublicId [in]
The declared public identifier for the external DTD subset or Null (if none was declared).
cchPublicId [in]
The length of the public identifier.
pwchSystemId [in]
The declared system identifier for the external DTD subset or Null (if none was declared).
cchSystemId [in]
The length of the system identifier.

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

endDocument Method | endDTD Method | startDocument | startElement Method | startEntity Method

Applies to: ISAXLexicalHandler/IVBSAXLexicalHandler Interface


endEntity Method

Indicates that the reader has opened and finished processing an externally defined entity in the content of the document.

[Visual Basic]

Implementation Syntax

Sub endEntity(strName As String)

Parameters

strName
The name of the entity.

Return Values

If failed, the LexicalHandler raises a trappable error.

[C/C++]

Syntax

HRESULT EndEntity(
   [in] const wchar_t * pwchName,
   [in] int cchName);

Parameters

pwchName [in]
The name of the entity. For parameter entities, the name begins with "%".
cchName [in]
The length of the entity name.

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

startEntity Method

Applies to: ISAXLexicalHandler/IVBSAXLexicalHandler Interface


startEntity Method

Indicates that the reader has opened and started to process an internally or externally defined entity in the content of the document.

[Visual Basic]

The reporting of parameter entities, including any external document type definition (DTD) subset, is optional. SAX2 (Simple API for XML) drivers that support a LexicalHandler may not support reporting of entities. Use the "http://xml.org/sax/features/lexical-handler/parameter-entities" feature to query or control the reporting of parameter entities.

The reader reports general entities with their regular names, parameter entities with '%' prepended to their names, and any external DTD subset with the pseudo-entity name "[dtd]".

When a reader driver provides these events, all other events must be properly nested within startEntity/endEntity events. There is no additional requirement that events from DeclHandler or DTDHandler be properly ordered.

Note The skippedEntity event, which is part of the ContentHandler interface, reports skipped entities.

Because of the streaming event model that SAX uses, some entity boundaries cannot be reported under any circumstances:

  • General entities within attribute values.
  • Parameter entities within declarations.

These are silently expanded, with no indication of where the original entity boundaries were.

Furthermore, the boundaries of character references (which are not really entities anyway) are not reported.

Implementation Syntax

Sub startEntity(strName As String)

Parameters

strName
The name of the entity. If it is a parameter entity, the name begins with '%'. If the parameter is an external DTD subset, it uses "[dtd]".

Return Values

If failed, the LexicalHandler raises a trappable error.

[C/C++]

The reader never reports entity references in attribute values, as well as the start and end of the document entity. In addition, the reader reports the start and end of the external document type definition (DTD) subset using the pseudo-name "[dtd]". All other events must be properly nested within the startEntity/endEntity events. Note that skipped entities will be reported through the skippedEntity event.

Entities are references to other content, which can be a piece of text or a large external file. Declaring an entity is done within a DTD. Entities always have two parts, the declaration and the reference. For example, consider the following entity reference:

<!ENTITY CompName "Microsoft® Corporation">

This entity can be referenced as follows:

&CompName; is an industry leader.

Which is interpreted as:

Microsoft® Corporation is an industry leader.

XML offers two kinds of entities—general entities and parameter entities. General entities, defined in DTDs, substitute the entity value within a document, as shown in the preceding example. Parameter entities link the content of additional DTD files to a DTD, or act as an abbreviation for frequently repeated declarations. To distinguish between these two types of entities, general entities use an ampersand (&) while parameter entities use the percent sign (%).

The reporting of parameter entities (including the DTD subset) is strictly optional. To allow the reader to recognize external entities, you use the putFeature method of the ISAXXMLReader interface to set the "http://xml.org/sax/features/lexical-handler/external-general-entities" and "http://xml.org/sax/features/lexical-handler/external-parameter-entities" features. The reader reports the general entities with their regular names, parameter entities have "%" prepended to their names, and the external DTD subset has the pseudo-entity name "[dtd]". When the reader reports these events, all other events must be properly nested within startEntity and endEntity events.

Syntax

HRESULT startEntity(
   [in] const wchar_t * pwchName,
   [in] int cchName);

Parameters

pwchName [in]
The name of the entity. For parameter entities, the name begins with "%".
cchName [in]
The length of the entity name.

Return Values

S_OK
The value returned if no errors occur.
E_FAIL
The value returned if the parse operation should be aborted.

See Also

endEntity Method| ISAXXMLReader/IVBSAXXMLReader Interface | putFeature Method

Applies to: ISAXLexicalHandler/IVBSAXLexicalHandler Interface


ISAXLocator Interface

The ISAXLocator/IVBSAXLocator interface associates a SAX2 event with a document location.

[Visual Basic]

The SAX2 reader provides location information by implementing this interface and passing an instance to the application, using the documentLocator property of the IVBSAXContentHandler interface. The application can use the Locator object to get the property values defined for this interface. These values describe location information associated with the current event, such as system ID, public ID, line number, and column number of any ContentHandler event in the XML source document.

Properties

columnNumber | Returns the column number where the current document event ends.
lineNumber | Returns the line number where the current document event ends.
publicId | Returns the public identifier for the current document event.
systemId | Returns the system identifier for the current document event.

[C/C++]

The SAX2 reader provides location information by implementing this interface and passing an instance to the application using the putDocumentLocator method of the ISAXContentHandler interface. The application can use the Locator object to obtain the location of any other document handler event in the XML source document.

The Locator object has a one-to-one relationship with the reader. As a result, each new event updates the information inside the Locator object. For example, an application saves a reference to the Locator object for handler call A. After that, the application tries to access the Locator object in handler call B. The information provided by the Locator object is now specific to handler call B because the object updates with each event. Correct usage for the Locator object is to save a reference to it within the ContentHandler and access it from there. For ErrorHandler methods, the Locator object is passed as a parameter.

Methods

getColumnNumber | Returns the column number where the current document event ends.
getLineNumber | Returns the line number where the current document event ends.
getPublicId | Returns the public identifier for the current document event.
getSystemId | Returns the system identifier for the current document event.

Requirements

Implementation: msxml4.dll

[C/C++]

Header and LIB files: msxml2.h, msxml2.lib

Remarks

Results returned by the object are valid only during the scope of each document handler method. The application receives unpredictable results if it attempts to use the locator at any other time. If the reader supplies a locator, it must do so before reporting any other document events. If no locator is set by the time the application receives the startDocument method event, the application should assume that a locator is not available.

See Also

documentLocator Property (Visual Basic) | putDocumentLocator Method (C/C++) | ISAXContentHandler/IVBSAXContentHandler Interface | startDocument Method


columnNumber Property (Visual Basic)

Returns the column number where the current document event ends.

This is the number of the first character following the current document event. The first column in a line is position 1.

Implementation Syntax

Property columnNumber As Long

Usage Syntax

NumVal=IVBSAXLocator.columnNumber

Return Values

If failed, returns -1 and raises a trappable error.

Remarks

The columnNumber property is read-only.

See Also

lineNumber Property (Visual Basic)

Applies to: IVBSAXLocator Interface


lineNumber Property (Visual Basic)

Returns the line number where the current document event ends.

This is the number of the line in which the first character following the current document event appears.

Implementation Syntax

Property lineNumber As Long

Usage Syntax

NumVal = IVBSAXLocator.lineNumber

Return Values

If failed, returns -1 and raises a trappable error.

Remarks

The lineNumber property is read-only.

See Also

columnNumber Property (Visual Basic)

Applies to: IVBSAXLocator Interface


publicId Property (Visual Basic)

Returns the public identifier for the current document event. A public identifier identifies a public domain file located in a publicly accessible place.

Implementation Syntax

Property publicId As String

Usage Syntax

StrVal = IVBSAXLocator.publicId

Return Values

Null if a publicID is not available.

Remarks

The publicID property is read-only.

See Also

systemId Property (Visual Basic)

Applies to: IVBSAXLocator Interface


systemId Property (Visual Basic)

Returns the system identifier for the current document event. A system identifier represents a file located on the local file system or network.

Implementation Syntax

Property systemId As String

Usage Syntax

StrVal = IVBSAXLocator.publicId

Return Values

Null if a system identifier is not available.

Remarks

The systemId property is read-only.

See Also

publicId Property (Visual Basic)

Applies to: IVBSAXLocator Interface


getColumnNumber Method (C/C++)

Returns the column number where the current document event ends.

This is the number of the first character after the text associated with the document event. The getColumnNumber method is permitted to show position within the text associated with the text event.

Syntax

HRESULT getColumnNumber(
   [out, retval] int * pnColumn);

Parameters

pnColumn [out, retval]
The column number (the first column in a line is #1). The pnColumn is –1 if the Locator object is not associated with some source input or a position within the source input.

Return Values

S_OK
The value returned if column number returned successfully.

See Also

getLineNumber Method (C/C++)

Applies to: ISAXLocator Interface


getLineNumber Method (C/C++)

Returns the line number where the current document event ends.

This is the line position of the first character after the text associated with the document event. This method is permitted to show position within the text associated with the text event.

Syntax

HRESULT getLineNumber(
   [out, retval] int * pnLine);

Parameters

pnLine [out, retval]
The line number. The pnLine is –1 if the Locator object is not associated with some source input or a position within the source input.

Return Values

S_OK
The value returned if line number returned successfully.

See Also

getColumnNumber Method (C/C++)

Applies to: ISAXLocator Interface


getPublicId Method (C/C++)

Returns the public identifier for the current document event. A public identifier identifies a public domain file located in a publicly accessible place.

Syntax

HRESULT getPublicId(
   [out, retval] const wchar_t ** ppwchPublicId);

Parameters

ppwchPublicId [out, retval]
The public identifier or Null (if none is available).

Return Values

S_OK
The value returned if the public identifier is returned successfully; Null if no public identifier is available.

See Also

getSystemId Method (C/C++)

Applies to: ISAXLocator Interface


getSystemId Method (C/C++)

Returns the system identifier for the current document event. A system identifier represents a file located on the local file system or network.

Syntax

HRESULT getSystemId(
   [out, retval] const wchar_t ** ppwchSystemId);

Parameters

ppwchSystemId [out, retval]
The system identifier or Null (if none is available).

Return Values

S_OK
The value returned if the system identifier is returned successfully; Null if no system identifier is available.

See Also

getPublicId Method (C/C++)

Applies to: ISAXLocator Interface


ISAXXMLFilter Interface

The ISAXXMLFilter/IVBSAXXMLFilter interface provides a convenient base for creating an XML filter by passing on all ISAXEntityResolver/IVBSAXEntityResolver, ISAXDTDHandler/IVBSAXDTDHandler, ISAXContentHandler/IVBSAXContentHandler, and ISAXErrorHandler/IVBSAXErrorHandler events automatically. An XML filter is like an XML reader, except that it obtains its events from another XML reader rather than a primary source, such as an XML document or a database. Filters can modify a stream of events as they pass on to their final application.

[Visual Basic]

The IVBSAXXMLFilter interface is derived from the IDispatch interface, not the IVBSAXXMLReader interface.

Properties

parent Sets or gets the instance of the reader that is the parent of the IVBSAXXMLFilter.

[C/C++]

Methods

getParent | Gets a reference to the instance of ISAXXMLReader that was set by the putParent method.
putParent | Sets the parent of the filter to an instance of ISAXXMLReader.

Requirements

Implementation: msxml4.dll

[C/C++]

Header and LIB files: msxml2.h, msxml2.lib

See Also

ISAXContentHandler/IVBSAXContentHandler | ISAXDTDHandler/IVBSAXDTDHandler | ISAXEntityResolver/IVBSAXEntityResolver | ISAXErrorHandler/IVBSAXErrorHandler


getParent Method (C/C++)

Gets a reference to the instance of ISAXXMLReader that was set by the putParent method.

Syntax

HRESULT getParent(
   [out, retval] ISAXXMLReader ** ppReader);

Parameters

ppReader [out, retval]
The instance of the reader in use.

Remarks

The argument may not be Null.

Return Values

S_OK
The value returned when the parent is returned as expected.

See Also

putParent Method (C/C++)

Applies to: ISAXXMLFilter Interface


putParent Method (C/C++)

Sets the parent of the filter to an instance of ISAXXMLReader.

Syntax

HRESULT putParent(
   [in] ISAXXMLReader * pReader);

Parameters

pReader [in]
The instance of the ISAXXMLReader to use as the parent.

Return Values

S_OK
The value returned when the instance of ISAXXMLReader is set as expected.

Remarks

This method allows the application to link the filter to a parent reader (which may be another filter). The argument may not be Null.

See Also

getParent Method (C/C++)

Applies to: ISAXXMLFilter Interface


parent Property (Visual Basic)

Sets or gets the instance of the reader that is the parent of the IVBSAXXMLFilter.

Implementation Syntax

Property parent As SAXXMLReader

Usage Syntax

To set the parent property

Set oIVBSAXFilter.parent = oSAXXMLReader

To get the parent property

Set oSAXXMLReader = oIVBSAXFilter.parent

Remarks

The parent property is read/write.

See Also

Applies to: IVBSAXXMLFilter Interface


ISAXXMLReader Interface

The ISAXXMLReader/IVBSAXXMLReader interface allows an application to set and query features and properties in the Microsoft® XML Parser (MSXML), register event handling for document processing, and initiate a document parse. MSXML provides the following coclasses that implement this interface.

SAXXMLReader
The version-independent coclass. Uses the most current implementation.

(CLSID_SAXXMLReader: 079aa557-4a18-424a-8eee-e39f0a8d41b9)

SAXXMLReader30
The version-dependent coclass. Ties the application to msxml3.dll.

(CLSID_SAXXMLReader30: 3124c396-fb13-4836-a6ad-1317f1713688)

SAXXMLReader40
The version-dependent coclass. Ties the application to msxml4.dll.

(CLSID_SAXXMLReader40: 88d969c7-f192-11d4-a65f-0040963251e5)

With MSXML 4.0, you can now throw SAX events from a DOMDocument object by specifying the DOMDocument object as the input parameter for the Parse method. For more information, see Throw SAX Events from a DOMDocument Object.

Controlling Reader Behavior

You can use the following methods to observe and control the behavior of the reader:

getFeature
Allows an application to ask the reader if it supports a feature.
putFeature
Allows an application to request that the reader turn a feature on or off.

Supported Features and Properties

The Microsoft COM/Visual Basic® implementation of SAX2 supports the following features (for example, a property whose value is Boolean).

  • "http://xml.org/sax/features/namespaces"
  • "http://xml.org/sax/features/namespace-prefixes"
  • "http://xml.org/sax/features/external-general-entitities"
  • "http://xml.org/sax/features/external-parameter-entities"
  • "normalize-line-breaks"
  • "server-http-request"
[Visual Basic]

The reader recognizes the "http://xml.org/sax/features/string-interning" and "http://xml.org/sax/features/validation" features. However, you cannot set these features in the current SAX2 implementation.

The reader also provides the getProperty and putProperty methods for getting and setting these properties.

  • "http://xml.org/sax/properties/lexical-handler"
  • "http://xml.org/sax/properties/declaration-handler"
  • "xmldecl-encoding"
  • "xmldecl-version"
  • "xmldecl-standalone"

Methods

getFeature | Returns the Boolean value of a feature.
putFeature | Sets the value of a feature.
getProperty | Returns the value of a property (as a string), for any qualified Uniform Resource Identifier (URI).
putProperty | Sets the value of a property.
parse | Parses an XML document or a DOMDocument object.
parseURL | Parses an XML document from a system identifier.

[Visual Basic]

The IVBSAXXMLReader interface is implemented in the Simple API for XML (SAX2) applications to manage and execute the parsing of an XML document.

Creating an Instance of the Reader

Typically, you create an instance of the reader in the Main form of a Visual Basic application. For example, first you declare a variable for holding a reference to the IVBSAXXMLReader or IVBSAXXMLReader30 interface. You then create an instance of the reader and assign the interface to the object variable as follows:

    Dim reader As SAXXMLReader
    Set reader = New SAXXMLReader

Creating an Instance of a Handler

After you create an instance of the reader, you can create an instance of a ContentHandler or ErrorHandler, and then set them as properties of the reader object using the contentHandler and errorHandler properties.

The following code sample declares variables for the ContentHandler and ErrorHandler implementations, creates instances of these two handlers, and registers these handlers with the reader object by defining them as properties of the reader.

    Dim reader As SAXXMLReader
    Dim contentHandler As ContentHandlerImpl
    Dim errorHandler As ErrorHandlerImpl

    Set reader = New SAXXMLReader
    Set contentHandler = New ContentHandlerImpl
    Set errorHandler = New ErrorHandlerImpl
    Set reader.contentHandler = contentHandler
    Set reader.errorHandler = errorHandler

Properties

baseURL | Sets the base URL for the current document.
contentHandler | Sets the current ContentHandler.
dtdHandler | Sets the current DTDHandler.
entityResolver | Sets the current EntityResolver.
errorHandler | Registers or returns the current ErrorHandler.
secureBaseURL | Sets the secure base URL for the document.

[C/C++]

Registering Handlers

An application can set and query features in the reader, register event handlers for document processing, and initiate a document parse. With this COM/C++ implementation of SAX2, the reader can use the following methods to register the corresponding handlers:

putContentHandler
Registers a ContentHandler.
putDTDHandler
Registers a DTDHandler.
putErrorHandler
Registers an ErrorHandler.

Methods

In addition to the preceding methods, the following also apply to the ISAXXMLReader interface.

getBaseURL | Returns the base URL for the document.
putBaseURL | Sets the base URL for the document.
getContentHandler | Returns the current ContentHandler.
putContentHandler | Allows an application to register a ContentHandler.
getDTDHandler | Returns the current DTDHandler.
putDTDHandler | Allows an application to register a DTDHandler.
getEntityResolver | Returns the current EntityResolver.
putEntityResolver | Allows an application to register an EntityResolver.
getErrorHandler | Returns the current ErrorHandler.
putErrorHandler | Allows an application to register an ErrorHandler.
getSecureBaseURL | Returns the secure base URL for the document.
putSecureBaseURL | Sets the secure base URL for the document.

Requirements

Implementation: msxml4.dll, msxml2.lib

[C/C++]

Header and LIB files: msxml2.h, msxml2.lib

Version-Independent ProgID: SAXXMLReader
Version-Independent CLSID: 079aa557-4a18-424a-8eee-e39f0a8d41b9
Version 3.0 Dependent ProgID: SAXXMLReader30

Version 3.0 Dependent CLSID: 3124c396-fb13-4836-a6ad-1317f1713688

Version 4.0 Dependent ProgID: SAXXMLReader40

Version-Dependent CLSID: 88d969c7-f192-11d4-a65f-0040963251e5


getFeature Method

Returns the Boolean value of a feature.

The Microsoft® COM/Visual Basic® and COM/C++ implementation support the following features:

  • "http://xml.org/sax/features/namespaces"
  • "http://xml.org/sax/features/namespace-prefixes"
  • "http://xml.org/sax/features/external-general-entitities"
  • "http://xml.org/sax/features/external-parameter-entities"
  • "normalize-line-breaks"
  • "server-http-request"
[Visual Basic]

The Boolean value indicates if a feature is enabled or disabled. For example, setting the "http://xml.org/sax/features/namespaces" feature to True enables namespace processing during parsing.

Usage Syntax

strFeature = oSAXXMLReader.getFeature(strName)

Parameters

strName
The name of the current feature.

Return Values

The following table shows the current matrix of behavior for the getFeature method.

Feature | Returns
namespaces | Boolean (True/False). If successful, returns the value of the feature.
namespace-prefixes | Boolean (True/False). If successful, returns the value of the feature.
"normalize-line-breaks" | Boolean (True/False). If successful, returns the value of the feature.
"server-http-request" | Boolean (True/False). If successful, returns the value of the feature.
validation external-general-entities external-parameter-entities string-interning | Boolean. Returns a False value for the feature.
Other features | Trappable error.

Remarks

The IVBSAXXMLReader interface recognizes the following features:

"http://xml.org/sax/features/namespaces"
True — (default) Perform namespace processing.
False — This value is not returned.
Access — (parsing) Read-only; (not parsing) Read/write.
"http://xml.org/sax/features/namespace-prefixes"
True — Report the original prefixed names and attributes used for namespace
declarations in the qualified names (QNames) field.
False — (default) Do not report attributes used for namespace declarations and,
optionally, do not report original prefixed names.
Access — (parsing) Read-only; (not parsing) Read/write.
"http://xml.org/sax/features/external-general-entities"
True — Include all external general (text) entities.
False — (default) Do not include external general entities.
Access — (parsing) Read-only; (not parsing) Read/write.
"http://xml.org/sax/features/external-parameter-entities"
True — Include all external parameter entities, including the external document
type definition (DTD) subset.
False — (default) Do not include any external parameter entities, including the
external DTD subset.
Access — (parsing) Read-only; (not parsing) Read/write.
"normalize-line-breaks"
True — (default) Normalize CR-LF sequence into single LF, per XML 1.0
specifications.
False — Keep CR-LF intact, as usual in COM programming.
Access — (parsing) Read-only; (not parsing) Read/write.
"server-http-request"
True — Use the server-safe ServerXMLHTTP object for the parseURL method.
False — (default) Use WinInet component to get data through HTTP for
parseURL.
Access — (parsing) Read-only; (not parsing) Read/write.
[C/C++]

The feature name is any fully-qualified Uniform Resource Identifier (URI). The values for the namespaces and namespace-prefixes features may be available only in a specific context, such as before, during, or after a parse.

Syntax

HRESULT getFeature(
   [in] const wchar_t * pwchName,
   [out, retval] VARIANT_BOOL * pvfValue);

Parameters

pwchName [in]
The feature name (zero-terminated Unicode string).
pvfValue [out, retval]
The value of the feature (True or False).

Return Values

The following table lists the return values for the getFeature method.

Feature | Returns
namespaces namespace-prefixes | S_OK—Last successful putFeature argument.
external-general-entities external-parameter-entities | S_OK—Last successful putFeature argument.
"normalize-line-breaks" | S_OK—Last successful putFeature argument.
"server-http-request" | S_OK—Last successful putFeature argument.
validation string-interning | S_OK—False
Other features | E_INVALIDARG

Remarks

The following describes the settings and access for the features:

"http://xml.org/sax/features/namespaces"
True — (default) Perform namespace processing.
False — This value has no effect and returns E_FAIL.
Access — (parsing) Read-only; (not parsing) Read/write.
"http://xml.org/sax/features/namespace-prefixes"
True — Report the original prefixed names and attributes used for
namespace declarations in the qualified names (QNames) field.
False — (default) Do not report attributes used for namespace declarations and,
optionally, do not report original prefixed names.
Access (parsing) Read-only. (not parsing) Read/write.
"http://xml.org/sax/features/external-general-entities"
True — Include all external general (text) entities.
False — (default) Do not include external general entities.
Access — (parsing) Read-only; (not parsing) Read/write.
"http://xml.org/sax/features/external-parameter-entities"
True — Include all external parameter entities, including the external document
type definition (DTD) subset.
False — (default) Do not include any external parameter entities, including the
external DTD subset.
Access (parsing) Read-only; (not parsing) Read/write.
"normalize-line-breaks"
True — (default) Normalize CR-LF sequence into single LF per XML 1.0
specifications.
False — Keep CR-LF intact, as usual in COM programming.
Access — (parsing) Read-only; (not parsing) Read/write.
"server-http-request"
True — Use the server-safe ServerXMLHTTP object for the parseURL method.
False — (default) Use the WinInet component to get data through HTTP for
parseURL.
Access — (parsing) Read-only; (not parsing) Read/write.

The reader recognizes the "http://xml.org/sax/features/string-interning" and "http://xml.org/sax/features/validation" features. However, you cannot set these features in the current SAX2 implementation.

The behavior of the reader depends on the values of the namespaces and namespace-prefixes, as shown in the following table.

If namespaces is... and namespace-prefixes is... | True True | True False | False True | False False
Reports namespace names | Yes | Yes | Yes | Illegal
Reports startPrefixMapping and endPrefixMapping events | Yes | Yes | Yes | Illegal
Reports QNames | Yes | Yes | Yes | Illegal
Reports xmlns attributes | Yes | No | Yes | Illegal

The SAX2 specifications state the implementation must report QNames when the namespace or namespace-prefixes feature is set to False. namespace and namespace-prefixes features cannot both be set to False.

See Also

putFeature Method

Applies to: ISAXXMLReader/IVBSAXXMLReader Interface


putFeature Method

Sets the value of a feature.

Allows an application to control the behavior of a reader by setting the state of the supported features. The feature name is any qualified Uniform Resource Identifier (URI). The ISAXXMLReader interface recognizes the following features:

  • "http://xml.org/sax/features/namespaces"
  • "http://xml.org/sax/features/namespace-prefixes"
  • "http://xml.org/sax/features/external-general-entitities"
  • "http://xml.org/sax/features/external-parameter-entities"
  • "normalize-line-breaks"
  • "server-http-request"

The values for the namespaces and namespace-prefixes features may be available only in a specific context, such as before, during, or after a parse.

[Visual Basic]

Usage Syntax

oSAXXMLReader.putFeature(strName, vfValue)

Parameters

strName
The name of the current feature.
vfValue
A Boolean expression (True/False) specifying whether the feature is on or off.

Return Values

The following table shows the return values for the putFeature method.

Feature | Returns
Namespaces | If failed, trappable error.
Namespace-prefixes | If failed, trappable error.
"normalize-line-breaks" | If failed, trappable error.
"server-http-request" | If failed, trappable error.
validation external-general-entities external-parameter-entities string-interning | If failed, trappable error.
Other features | Trappable error

[C/C++]

Syntax

HRESULT putFeature(
   [in] const wchar_t * pwchName,
   [in] VARIANT_BOOL vfValue);

Parameters

pwchName [in]
The name of the feature (zero-terminated Unicode string).
vfValue [in]
The current state of the feature (True or False).

Return Values

The following table lists the return values for the putFeature method.

Feature | Returns
namespaces | S_OK (not parsing and legal) E_FAIL if namespace-prefixes is False. (parsing or illegal)
namespace-prefixes | S_OK (not parsing and legal) E_FAIL if namespaces is False. (parsing or illegal)
external-general-entities external-parameter-entities | S_OK (not parsing) E_FAIL (parsing or illegal)
"normalize-line-breaks" | S_OK
"server-http-request" | S_OK (not parsing) E_FAIL (parsing)
validation string-interning | E_FAIL
Other features | E_INVALIDARG

Remarks

The following describes the possible settings and access for features:

"http://xml.org/sax/features/namespaces"
True — (default) Perform namespace processing.
False — This value has no effect and returns E_FAIL.
Access — (parsing) Read-only; (not parsing) Read/write.
"http://xml.org/sax/features/namespace-prefixes"
True — Report the original prefixed names and attributes used for namespace
declarations in the QNames (qualified names) field.
False — (default) Do not report attributes used for namespace declarations and,
optionally, do not report original prefixed names.
Access — (parsing) Read-only; (not parsing) Read/write.
"http://xml.org/sax/features/external-general-entities"
True — Include all external general (text) entities.
False — (default) Do not include external general entities.
Access — (parsing) Read-only; (not parsing) Read/write.
"http://xml.org/sax/features/external-parameter-entities"
True — Include all external parameter entities, including the external document type definition (DTD) subset.
False — (default) Do not include any external parameter entities, including the
external DTD subset.
Access — (parsing) Read-only; (not parsing) Read/write.
"normalize-line-breaks"
True — (default) Normalize CR-LF sequence into single LF per XML 1.0
specifications.
False — Keep CR-LF intact, as usual in COM programming.
Access — (parsing) Read-only; (not parsing) Read/write.
"server-http-request"
True — Use the server-safe ServerXMLHTTP object for the parseURL method.
False — (default) Use the WinInet component to get data through HTTP for
parseURL.
Access — (parsing) Read-only; (not parsing) Read/write.

The reader recognizes the "http://xml.org/sax/features/string-interning" and "http://xml.org/sax/features/validation" features. However, you cannot set these features in the current SAX2 implementation.

The behavior of the reader depends on the values of the namespaces and namespace-prefixes features, as shown in the following table.

If namespaces is... and namespace-prefixes is... | True True | True False | False True | False False
Reports namespace names | Yes | Yes | Yes | Illegal
Reports startPrefixMapping and endPrefixMapping events | Yes | Yes | Yes | Illegal
Reports QNames | Yes | Yes | Yes | Illegal
Reports xmlns attributes | Yes | No | Yes | Illegal

SAX2 specifications state the implementation must report QNames when the namespace or namespace-prefixes feature is set to False. namespace and namespace-prefixes features cannot both be set to False.

See Also

getFeature Method

Applies to: ISAXXMLReader/IVBSAXXMLReader Interface


getProperty Method

Returns a property's value (as a string), for any qualified Uniform Resource Identifier (URI).

[Visual Basic]

Usage Syntax

varValue = oSAXXMLReader.getProperty(strName)

Parameters

varValue
The corresponding data type of the property.

Return Values

The following table shows the return values for the getProperty method.

Property | Returns
lexical-handler declaration-handler | The specified handler.
"xmldecl-encoding" "xmldecl-version" "xmldecl-standalone" | Value or trappable error (if value is not available).
dom-node xml-string | Empty value.
Other properties | Trappable error.

[C/C++]

Returns the value of a property. The property name is any qualified Uniform Resource Identifier (URI).

It is possible for a reader to recognize a property name but not be able to return its state. Although a core set of properties is defined, a reader is not required to recognize specific property names. Some property values may be available only in a specific context, such as before, during, or after a parse.

Syntax

HRESULT getProperty(
   [in] const wchar_t * pwchName,
   [out, retval] VARIANT * pvarValue);

Parameters

pwchName [in]
The property's name (zero-terminated Unicode string).
pvarValue [out, retval]
The corresponding data type for the property.

Return Values

The following table lists the return values for the getProperty method.

Property | Returns
lexical-handler declaration-handler | S_OK—The current value is returned.
"xmldecl-encoding" "xmldecl-version" "xmldecl-standalone" | S_OK—The current value is parsed. E_FAIL—Not parsing.
dom-node xml-string | S_OK—An empty value is returned.
Other properties | E_INVALIDARG—The property is not recognized.

Remarks

The ISAXXMLReader interface recognizes the following properties:

"http://xml.org/sax/properties/lexical-handler"
This is an optional extension handler for lexical events like comments.
Datatype — ISAXXMLLexicalHandler.
Access — Read/write.
"http://xml.org/sax/properties/declaration-handler"
This is an optional extension handler for declaration events.
Datatype — ISAXXMLDeclHandler.
Access — Read/write.
"xmldecl-encoding"
Encoding declared in the XML header of the currently parsed document. This data is unavailable until the reader parses the XML header.
Datatype — BSTR*.
Default — Empty (if there is no XML declaration or if a property is not found).
Access — (parsing) Read: (not parsing) None.
"xmldecl-version"
Version declared in the XML header of currently parsed document. This data is unavailable until the reader parses the XML header.
Datatype — BSTR*.
Default — Empty (if there is no XML declaration).
Access — (parsing) Read; (not parsing) None.
"xmldecl-standalone"
Declared in the XML header of currently parsed document. This data is unavailable until the reader parses the XML header.
Datatype — BSTR* ("yes" or "no").
Default — Empty (if there is no XML declaration or if a property is not found).
Access — (parsing) Read; (not parsing) None.
Note The "xmldecl-encoding", "xmldecl-version", and "xmldecl-standalone" properties provide information about the presence and content of the XML header. However, XML header information was designed for low-level reader and parser use, not for applications.

See Also

putProperty Method

Applies to: ISAXXMLReader/IVBSAXXMLReader Interface


putProperty Method

Sets the value of a property. The property name is any qualified Uniform Resource Identifier (URI).

[Visual Basic]

Usage Syntax

oSAXXMLReader.putProperty(strName, varValue)

Parameters

strName
The property's name.
varValue
The corresponding data type of the property.

Return Values

The following table shows the return values for the putProperty method.

Property | Returns
lexical-handler declaration-handler | Trappable error (if unable to set property).
"xmldecl-encoding" "xmldecl-version" "xmldecl-standalone" | Trappable error.
Other properties | Trappable error

[C/C++]

Although a core set of properties is defined, a reader is not required to recognize any specific property names. Some property values may be available only in a specific context, such as before, during, or after a parse.

Syntax

HRESULT putProperty(
   [in] const wchar_t * pwchName,
   [in] VARIANT varValue);

Parameters

pwchName [in]
The property's name (zero-terminated Unicode string).
varValue [in]
The corresponding data type of the property.

Return Values

The following table lists the return values for the putProperty method.

Property | Returns
lexical-handler declaration-handler | S_OK (not parsing) E_FAIL (parsing)
"xmldecl-encoding" "xmldecl-version" "xmldecl-standalone" | E_FAIL
dom-node xml-string | E_FAIL
Other properties | E_INVALIDARG

Remarks

The ISAXXMLReader interface recognizes the following properties:

"http://xml.org/sax/properties/lexical-handler"
This is an optional extension handler for lexical events, like comments.
Datatype — ISAXXMLLexicalHandler.
Access — Read/write.
"http://xml.org/sax/properties/declaration-handler"
This is an optional extension handler for declaration events.
Datatype — ISAXXMLDeclHandler
Access — Read/write.
"xmldecl-encoding"
Encoding declared in the XML header of the currently parsed document. This data is unavailable until the reader parses the XML header.
Datatype — BSTR.
Default — Empty (if there is no XML declaration or a property is not found).
Access — (parsing) Read; (not parsing) None.
"xmldecl-version"
Version declared in the XML header of currently parsed document. This data is unavailable until the reader parses the XML header.
Datatype — BSTR.
Default — Empty (if there is no XML declaration).
Access — (parsing) Read; (not parsing) None.
"xmldecl-standalone"
Declared in the XML header of currently parsed document. This data is unavailable until the reader parses the XML header.
Datatype — BSTR ("yes" or "no").
Default — Empty (if there is no XML declaration or if a property is not found).
Access — (parsing) Read; (not parsing) None.
Note The "xmldecl-encoding", "xmldecl-version", and "xmldecl-standalone" properties provide information about the presence and content of the XML header. However, XML header information was designed for low-level reader and parser use, not for applications.

See Also

getProperty Method

Applies to: ISAXXMLReader/IVBSAXXMLReader Interface


parse Method

Parses an XML document or a DOMDocument object.

[Visual Basic]

An application can use this method to instruct the reader to begin parsing a document from any valid input source, including a DOMDocument object, character stream, byte stream, or Uniform Resource Identifier (URI). An application cannot invoke this method while a parsing is in progress. Instead, it should create a new instance of the reader for each nested XML document. After parsing is complete, an application can reuse the same reader object, possibly with a different input source.

Usage Syntax

oSAXXMLReader.parse(varInput)

Parameters

varInput
Variant containing input source to parse from. Supported VARIANT types are: VT_BSTR, SafeArray of bytes (VT_ARRAYVT_UI1), VT_UNK(IStream) and VT_UNK(ISequentialStream).

Remarks

During parsing, the reader provides information about the XML document through the registered event handlers. If an error occurs during parsing, the reader calls the appropriate method of the ErrorHandler. The ErrorHandler always returns the internal error code to the parse method, even if the ErrorHandler raises a user-defined error.

Example

The following example loads books.xml into a DOMDocument object, specifies the object as a parameter of the parse method, and then displayss the result in a message box.

'create a DOMDocument object
Dim xmlDoc As New DOMDocument
'create the reader
Dim rdr As New SAXXMLReader
'create the writer
Dim wrt As New MXXMLWriter

On Error GoTo errorHandler

xmlDoc.async = False
xmlDoc.Load ("books.xml")

wrt.byteOrderMark = True
wrt.omitXMLDeclaration = False
wrt.indent = True

'set the writer to the content handler
Set rdr.contentHandler = wrt
Set rdr.dtdHandler = wrt
Set rdr.errorHandler = wrt
rdr.putProperty "http://xml.org/sax/properties/lexical-handler", wrt
rdr.putProperty "http://xml.org/sax/properties/declaration-handler", wrt

'parse the DOMDocument object
rdr.parse xmlDoc

'show the results in a message box
MsgBox wrt.output

Exit Sub

errorHandler:
    HandleErrors
End Sub

Private Function HandleErrors()
    MsgBox Err.Description
End Function
[C/C++]

The application can use this method to instruct the reader to begin parsing a document from a variety of sources. Supported VARIANT types are: VT_BSTR, SafeArray of bytes (VT_ARRAYVT_UI1), VT_UNK(IStream), and VT_UNK(ISequentialStream). One-level referencing is also permitted.

   VT_BYREF | VT_VARIANT d
   VT_BYREF | VT_VARIANT -> VT_BSTR
   VT_BYREF | VT_VARIANT -> IStream
   VT_BYREF | VT_VARIANT -> IXMLDOMDocument
   VT_BYREF | VT_VARIANT -> VT_ARRAY|VT_UI1

An application cannot invoke this method while parsing is in progress. Instead, it should create a new instance of the reader for each nested XML document. After parsing is complete, an application can reuse the same reader object, possibly with a different input source.

Syntax

HRESULT parse (
   [in] VARIANT varInput);

Parameters

varInput [in]
Variant containing the input source to parse from. Supported VARIANT types are: VT_BSTR, SafeArray of bytes (VT_ARRAYVT_UI1), VT_UNK (IStream), and VT_UNK(ISequentialStream), VT_UNK(IXMLDOMDocument), VT_DISP(XMLDOMDocument).

Return Values

S_OK
The value returned if parsing is successful.
E_INVALIDARG
The value returned if varInput is not a recognized input source.
Other
The parser error code or the code returned by the custom ErrorHandler.

Remarks

During parsing, the reader provides information about the XML document through the registered event handlers. If an error occurs during parsing, the reader calls the appropriate method of the ISAXErrorHandler interface. If the ErrorHandler returns anything but S_OK, parsing is aborted and the parse method returns the internal error that stopped the parser. The ErrorHandler always returns the internal error code, even if the ErrorHandler returns a user-defined HRESULT to the parse method. The reader can return a number of return codes, including, but not limited to: E_ACCESSDENIED, INET_E_OBJECT_NOT_FOUND, INET_E_DOWNLOAD_FAILURE, MSG_E_BADSTARTNAMECHAR, or MSG_E_MISSINGSEMICOLON.

See Also

Throw SAX Events from a DOMDocument Object | DOMDocument | ISAXErrorHandler Interface | contentHandler Property (Visual Basic) | dtdHandler Property (Visual Basic) | entityResolver Property (Visual Basic) | errorHandler Property (Visual Basic) | putContentHandler Method (C/C++) | putDTDHandler Method (C/C++) | putEntityResolver Method (C/C++) | putErrorHandler Method (C/C++)

Applies to: ISAXXMLReader/IVBSAXXMLReader Interface


parseURL Method

Parses an XML document from a system identifier (URI).

Note If you are using Microsoft® Internet Explorer 5.5, you may get an E_PENDING error when you attempt to load an XML file that has external entities. To correct this situation, upgrade to Internet Explorer 5.5, Service Pack 1.
[Visual Basic]

The parseURL method is a shortcut for reading a document from a system identifier. If the system identifier is a URL, the application must fully resolve the URL before passing it to the reader.

Usage Syntax

oSAXXMLReader.parseURL(strURL)

Parameters

strURL
The URL to load.

Remarks

While parsing, the reader provides information about the XML document through the registered event handlers. If an error occurs during parsing, the reader calls the appropriate method of the ErrorHandler. The ErrorHandler always returns the internal error code to the parseURL method, even if the ErrorHandler raises a user-defined error.

[C/C++]

The base URL and secure base URL can be set by the putBaseURL and putSecureBaseURL methods. These methods are shortcuts for reading a document from a system identifier. If the system identifier is a URL, the application must fully resolve the URL before passing it to the reader.

Syntax

HRESULT ParseURL(
   [in] const wchar_t * pwchUrl);

Parameters

pwchUrl [in]
The URL (zero-terminated Unicode string) to load from.

Return Values

S_OK
The value returned if parsing is successful.
Other
Either the parser error code or the code returned by the custom ErrorHandler. Unresolved URLs, security, and network errors are returned in the same way.

Remarks

During parsing, the reader provides information about the XML document through the registered event handlers. If an error occurs during parsing, the reader calls the appropriate method of the ISAXErrorHandler : IUnknown interface. If the ErrorHandler returns anything but S_OK, parsing is aborted and the parseURL method returns the internal error that stopped the parser. The ErrorHandler always returns the internal error code, even if the ErrorHandler returns a user-defined HRESULT to the parseURL method. The reader can return a number of return codes, including, but not limited to: E_ACCESSDENIED, INET_E_OBJECT_NOT_FOUND, INET_E_DOWNLOAD_FAILURE, MSG_E_BADSTARTNAMECHAR, or MSG_E_MISSINGSEMICOLON.

See Also

baseURL Property (Visual Basic) | ISAXErrorHandler Interface | parse Method | putBaseURL Method (C/C++) | putSecureBaseURL Method (C/C++) | secureBaseURL Property (Visual Basic)

Applies to: ISAXXMLReader/IVBSAXXMLReader Interface


baseURL Property (Visual Basic)

Sets the base URL for the current document. The baseURL property is stored as a string.

Usage Syntax

For getting the base URL:

strbaseURL = oSAXXMLReader.baseURL

For setting the base URL:

oSAXXMLReader.baseURL = strBaseURL

Return Values

A trappable error if the application tries to set the baseURL property while parsing is in progress.

Example

Dim strURL As String
reader.baseURL = "http://My.web.site/"
strURL = reader.baseURL

Remarks

If a URL does not end with a slash or backslash, the text following the backslash is considered the destination file name. For example, "http://www.microsoft.com/msdn/" sets the base URL to "http://www.microsoft.com/msdn" while "http://www.microsoft.com/msdn" sets the base URL to "http://www.microsoft.com/".

See Also

secureBaseURL Property (Visual Basic)

Applies to: IVBSAXXMLReader Interface


contentHandler Property (Visual Basic)

Sets the current ContentHandler.

Usage Syntax

For getting the ContentHandler:

objcontentHandler = oSAXXMLReader.ContentHandler

For setting the ContentHandler:

oSAXXMLReader.ContentHandler = objcontentHandler

Example

Dim ContentHandler As ContentHandlerImpl
Set ContentHandler = New ContentHandlerImpl
reader.ContentHandler = ContentHandler

Remarks

The contentHandler property gets or sets the current ContentHandler from or to the IVBSAXContentHandler interface.

See Also

Applies to: IVBSAXXMLReader Interface


dtdHandler Property (Visual Basic)

Sets the current DTDHandler.

Usage Syntax

For getting the DTDHandler:

objdtdHandler = oSAXXMLReader.dtdHandler

For setting the DTDHandler:

oSAXXMLReader.dtdHandler = objdtdHandler

Remarks

The dtdHandler property gets or sets the current DTDHandler from or to the IVBSAXDTDHandler interface.

See Also

Applies to: IVBSAXXMLReader Interface


entityResolver Property (Visual Basic)

At this time, the EntityResolver property cannot be set for this implementation of the Simple API for XML (SAX2).

Sets the current EntityResolver.

Because the entityResolver property is not supported in the current SAX2 implementation, a trappable error is returned when you try to get or set the entityResolver property.

Usage Syntax

For getting the EntityResolver:

set objentityResolver = oSAXXMLReader.entityResolver

For setting the EntityResolver:

set oSAXXMLReader.entityResolver = objentityResolver

Remarks

The entityResolver property gets or sets the current EntityResolver from or to the IVBSAXEntityResolver interface.

See Also

Applies to: IVBSAXXMLReader Interface


errorHandler Property (Visual Basic)

Registers or returns the current ErrorHandler.

Usage Syntax

For getting the ErrorHandler:

objerrorHandler = oSAXXMLReader.errorHandler

For setting the ErrorHandler:

oSAXXMLReader.errorHandler = objErrorHandler

Remarks

The errorHandler property gets or sets the current ErrorHandler from or to the IVBSAXErrorHandler interface.

See Also

Applies to: IVBSAXXMLReader Interface


secureBaseURL Property (Visual Basic)

Sets the secure base URL for the document. If the secure base URL is not set, full access is allowed. The secure base URL cannot be set during parsing. The underlying runtime environment determines the response to the security violation.

By setting the secureBaseURL, the application requests security enforcement by the Microsoft® Internet Explorer security settings, which control behavior on the user's computer. This means that the user, not the application, controls Internet security settings.

To understand what the secure base URL is, consider this example. When a parser reads an XML file from the site "www.a.com", both the base URL and the secure base URL are the same: "www.a.com". Now, consider that in the XML file there is an external reference to the site "www.b.com". When reading the externally referenced file, the base URL will be "www.b.com", while the secure base URL is still "www.a.com".

Note For security reasons, the secure base URL cannot be set with script within the context of Internet Explorer.

Usage Syntax

For getting the secureBaseURL property:

strVal = oSAXXMLReader.secureBaseURL

For setting the secureBaseURL property:

oSAXXMLReader.errorHandler = objErrorHandler

Return Values

A trappable error if the application tries to set the secureBaseURL property during the parse operation.

See Also

baseURL Property (Visual Basic)

Applies to: IVBSAXXMLReader Interface


getBaseURL Method (C/C++)

Returns the base URL for the document.

Syntax

HRESULT getBaseURL(
   [out] const wchar_t ** ppwchBaseUrl);

Parameters

ppwchBaseUrl [out]
The base URL (zero-terminated Unicode string) for the document.

Return Codes

S_OK
The value returned if the URL is successfully returned.

Remarks

The base URL represents the URL of the current XML document. The reader uses this base URL to resolve relative links (either for those links related to the parseURL method or for external entities in an XML document). To resolve these links, the reader uses the base URL in much the same way that an Internet browser uses a Web page's URL to resolve relative links contained on that page.

The base URL may be a complete URL. However, the reader only uses that portion of the URL up to and including the final backslash when resolving links. For instance, the base URL for a document is "http://msdn.microsoft.com/xml/test.xml". The reader would then only use "http://msdn.microsoft.com/xml/" when resolving links.

Here is an example of how the reader uses the base URL to resolve links. The base URL for a document is "http://msdn.microsoft.com/xml/test.xml". In that document, there is a link for "mytest.xml". The reader would resolve this link as "http://msdn.microsoft.com/xml/mytest.xml".

See Also

putBaseURL Method (C/C++) | getSecureBaseURL Method (C/C++) | putSecureBaseURL Method (C/C++)

Applies to: ISAXXMLReader Interface


putBaseURL Method (C/C++)

Sets the base URL for the document. The base URL cannot be set during parsing.

Syntax

HRESULT putBaseURL(
   [in] const wchar_t * pwchBaseUrl);

Parameters

pwchBaseUrl [in]
The base URL (zero-terminated Unicode string) for the document.

Return Codes

S_OK
The value returned if the base URL is successfully set.
E_FAIL
The value returned if the application tries to set the base URL during parsing.

Remarks

The base URL represents the URL of the current XML document. The reader uses this base URL to resolve relative links (either for those links related to the parseURL method or for external entities in an XML document). To resolve these links, the reader uses the base URL in much the same way that an Internet browser uses a Web page's URL to resolve relative links contained on that page.

The base URL may be a complete URL. However, the reader only uses that portion of the URL up to and including the final backslash when resolving links. For instance, the base URL for a document is "http://msdn.microsoft.com/xml/test.xml". The reader would then only use "http://msdn.microsoft.com/xml/" when resolving links.

Here is an example of how the reader uses the base URL to resolve links. The base URL for a document is "http://msdn.microsoft.com/xml/test.xml". In that document, there is a link for "mytest.xml". The reader would resolve this link as "http://msdn.microsoft.com/xml/mytest.xml".

See Also

getBaseURL Method (C/C++) | getSecureBaseURL Method (C/C++) | putSecureBaseURL Method (C/C++)

Applies to: ISAXXMLReader Interface


getContentHandler Method (C/C++)

Returns the current ContentHandler. The ContentHandler is the class that is implemented to process the contents of a document.

Syntax

HRESULT getContentHandler(
   [out, retval] ISAXContentHandler ** ppHandler);

Parameters

ppHandler [out, retval]
The ContentHandler currently in use or Null (if a ContentHandler has not been set).

Return Values

S_OK
The value returned if the ContentHandler is successfully returned.

See Also

putContentHandler Method (C/C++)

Applies to: ISAXXMLReader Interface


putContentHandler Method (C/C++)

Allows an application to register a ContentHandler. If the application does not register a ContentHandler, all content events reported by the reader will be ignored. An application can register a new or different handler while in the middle of parsing a document, and the reader will immediately start using the new handler.

Syntax

HRESULT putContentHandler(
   [in] ISAXContentHandler * pHandler);

Parameters

pHandler [in]
The ContentHandler to register.

Return Values

S_OK
The value returned if the ContentHandler is successfully registered.

See Also

getContentHandler Method (C/C++)

Applies to: ISAXXMLReader Interface


getDTDHandler Method (C/C++)

Returns the current DTDHandler.

Syntax

HRESULT getDTDHandler(
   [out, retval] ISAXDTDHandler ** ppHandler);

Parameters

ppHandler [out, retval]
The DTDHandler currently in use or Null (if a DTDHandler has not been set).

Return Values

S_OK
The value returned if the DTDHandler is successfully returned.

See Also

putDTDHandler Method (C/C++)

Applies to: ISAXXMLReader Interface


putDTDHandler Method (C/C++)

Allows an application to register a DTDHandler. If the application does not register a DTDHandler, all DTD events reported by the reader are ignored. An application can register a new or different handler while in the middle of parsing a document, and the reader will immediately start using the new handler.

Syntax

HRESULT putDTDHandler(
   [in] ISAXDTDHandler * pHandler);

Parameters

pHandler [in]
The DTDHandler to register.

Return Values

S_OK
The value returned if the DTDHandler is successfully registered.

See Also

getDTDHandler Method (C/C++)

Applies to: ISAXXMLReader Interface


getEntityResolver Method (C/C++)

At this time, the EntityResolver property cannot be set for this implementation of the Simple API for XML (SAX2).

Returns the current EntityResolver. Currently, this method always returns Null because the EntityResolver property cannot be set in the current SAX2 implementation.

Syntax

HRESULT getEntityResolver(
   [out, retval] ISAXEntityResolver ** ppResolver);

Parameters

ppResolver [out, retval]
Null because the EntityResolver cannot be set in the current SAX2 implementation.

Return Values

S_OK
The value returned. The ppResolver value will always be Null.

See Also

putEntityResolver Method (C/C++)

Applies to: ISAXXMLReader Interface


putEntityResolver Method (C/C++)

At this time, the EntityResolver property cannot be set for this implementation of the Simple API for XML (SAX2).

Allows an application to register an EntityResolver. If the application does not register an EntityResolver, the reader performs its own default resolution. An application can register a new or different EntityResolver while in the middle of parsing a document, and the reader will immediately start using the new EntityResolver.

The ISAXEntityResolver interface provides a way to resolve references to external entities (data held in separate files identified by a system or public identifier). The reader automatically resolves internal entities, character references, and predefined entities. However, some applications build XML documents from databases and specialized input sources that use Uniform Resource Identifier (URI) types rather than URLs. When external entities cannot be found by URL, a SAX application should provide a class that implements the EntityResolver interface.

Syntax

HRESULT putEntityResolver(
   [in] ISAXEntityResolver * pResolver);

Parameters

pResolver [in]
The EntityResolver to register.

Return Values

E_FAIL
Always returned because the EntityResolver property cannot be set for the current SAX2 implementation.

See Also

getEntityResolver Method (C/C++) | ISAXEntityResolver Interface

Applies to: ISAXXMLReader Interface


getErrorHandler Method (C/C++)

Returns the current ErrorHandler.

Syntax

HRESULT getErrorHandler(
   [out,retval] ISAXErrorHandler ** ppHandler);

Parameters

ppHandler [out, retval]
The current ErrorHandler or Null (if an ErrorHandler has not been set).

Return Values

S_OK
The value returned if the ErrorHandler is successfully returned.

See Also

putErrorHandler Method (C/C++)

Applies to: ISAXXMLReader Interface


putErrorHandler Method (C/C++)

Allows an application to register an ErrorHandler. If the application does not register an ErrorHandler, all error events reported by the reader are ignored. It is strongly recommended that all Simple API for XML (SAX2) applications implement an ErrorHandler to avoid unexpected bugs. An application can register a new or different handler while in the middle of parsing a document, and the reader will immediately start using the new handler.

Syntax

HRESULT putErrorHandler(
   [in] ISAXErrorHandler * pHandler);

Parameters

pHandler [in]
The ErrorHandler to use.

Return Values

S_OK
The value returned if the ErrorHandler is successfully registered.

See Also

getErrorHandler Method (C/C++)

Applies to: ISAXXMLReader Interface


getSecureBaseURL Method (C/C++)

Returns the secure base URL for the document. If secure base URL is not set, full access is allowed. The secure base URL cannot be set during parsing.

Syntax

HRESULT getSecureBaseURL (
   [out, retval] const wchar_t ** ppwchSecureBaseUrl);

Parameters

ppwchSecureBaseUrl [out, retval]
The secure base URL (zero-terminated Unicode string).

Return Values

S_OK
The value returned if the secure base URL is successfully returned.

See Also

putSecureBaseURL Method (C/C++)

Applies to: ISAXXMLReader Interface


putSecureBaseURL Method (C/C++)

Sets the secure base URL for the document. If the secure base URL is not set, full access is allowed. The secure base URL cannot be set during parsing. The underlying run-time environment determines the response to the security violation.

By setting the secure base URL, the application requests security enforcement by the Microsoft® Internet Explorer security settings, which control behavior on the user's computer. This means that the user, not the application, controls Internet security settings.

To understand what the secure base URL is, consider this example. When a parser reads an XML file from the site "www.a.com", both the base URL and the secure base URL are the same: "www.a.com". Now, consider that in the XML file there is an external reference to the site "www.b.com". When reading the externally referenced file, the base URL will be "www.b.com", while the secure base URL is still "www.a.com".

Note For security reasons, the secure base URL cannot be set with script within the context of Internet Explorer.

Syntax

HRESULT putSecureBaseURL (
   [in] const wchar_t * pwchSecureBaseUrl

Parameters

pwchSecureBaseUrl [in]
The secure base URL (zero-terminated Unicode string).

Return Values

S_OK
The value returned if the secure base URL is successfully set.
E_FAIL
The value returned if the application tries to set the secure base URL during parsing.

See Also

getSecureBaseURL Method (C/C++)

Applies to: ISAXXMLReader Interface


SAX2 C++ Common Notices

Strings

In this implementation, all strings returned to handler callbacks consist of two parts: a pointer to the wchar buffer and the length of the string. This includes strings passed either directly, such as the element name for the startElement method, or indirectly, such as strings provided by ISAXAttributes and ISAXLocator classes. Strings returned from these components are owned by the components, not the calling process. Therefore, their memory should not be released, freed, or deleted. Strings, represented as a pointer to the character buffer and length, may be not zero-terminated.

When a string consists of both a pointer to the buffer and a length, the length always contains the correct length of the string: either it is zero-terminated or not. For input parameters, the representation of strings follows traditional zero-terminated Unicode string format, for example, rdr.putBase(L"http://microsoft.com/"). It's not guaranteed that the content of the string will still keep the value at the next call to a handler.

After any successful getProperty call, the caller should free the memory. The MXXML Simple API for XML (SAX2) property strings are the exception to the general COM rule that system-allocated objects are allocated by the data source and freed by the consumer.

Declaration Conflicts

The Microsoft® XML Parser (MSXML) implementation of SAX2 is nonvalidating. As a result, a validation error does not occur if the same element is declared twice, with different definitions, in an internal DTD. When element/entity declaration conflicts occur, the first declaration takes precedence.

Skipped Entities

If an entity is declared in an external DTD, MSXML SAX2 reports it as a skipped entity and the value of the nondeclared (skipped) entity is defaulted to empty. However, MSXML SAX2 does not report entities in attributes. They are quietly skipped.

Features

Features handled and recognized by SAXXMLReader are:

  • "http://xml.org/sax/features/namespaces"
  • "http://xml.org/sax/features/namespace-prefixes"
  • "http://xml.org/sax/features/external-general-entities"
  • "http://xml.org/sax/features/external-parameter-entities"
  • "normalize-line-breaks"
  • "server-http-request"

Properties

Properties handled and recognized by SAXXMLReader are:

  • "http://xml.org/sax/properties/lexical-handler"
  • "http://xml.org/sax/properties/declaration-handler"
  • "xmldecl-encoding"
  • "xmldecl-version"
  • "xmldecl-standalone"

Return Codes

All handlers may return either S_OK to continue or an error code other than S_OK. For error codes other than S_OK, parsing is aborted and the return code is returned by the parse(), parseURL(), or resume method.

Most parser methods may return general error codes like the following.

E_POINTER
Null instead of the pointer to parameter.
E_OUTOFMEMORY
Out of memory.
E_INVALIDARG
Input parameter is invalid.
E_FAIL
General failure.


SAX2 Visual Basic Common Notices

Visual Basic Wrappers

Microsoft® Visual Basic® wrappers are constructed from C++/COM interfaces by:

  • Replacing the "I" prefix in front of the interface/class name with "IVB".
  • Replacing all string representations from w_char_t*/int to BSTR. For handlers, strings should be passed by reference.
  • Replacing IerrorInfo parameters with BSTRs containing error messages.
  • Replacing HRESULT parameters with long.
  • Making all parameter names follow simplified Hungarian notation for Visual Basic. For example, strName is used in place of pwchName. Prefixes are "srt", "n", "l", and "o".
  • Wherever C++ uses NULL, Visual Basic uses VT_Empty.
  • All interfaces are derived from IDispatch.

Currently, Visual Basic and C++ wrappers are completely disconnected for the user. However, the same coclasses implement both C++ and VB interfaces.

Features

Features handled and recognized by SAXXMLReader are:

  • "http://xml.org/sax/features/namespaces"
  • "http://xml.org/sax/features/namespace-prefixes"
  • "http://xml.org/sax/features/external-general-entities"
  • "http://xml.org/sax/features/external-parameter-entities"
  • "normalize-line-breaks"
  • "server-http-request"

Properties

Properties handled and recognized by SAXXMLReader are:

  • "http://xml.org/sax/properties/lexical-handler"
  • "http://xml.org/sax/properties/declaration-handler"
  • "http://xml.org/sax/features/external-general-entities"
  • "http://xml.org/sax/features/external-parameter-entities"
  • "xmldecl-encoding"
  • "xmldecl-version"
  • "xmldecl-standalone"

Base interface

All interfaces are derived from IDispatch.


XML Glossary

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

A

attribute

B

C

Cascading Style Sheets (CSS)

CDF

Channel Definition Format (CDF)

character data

complex data type

D

data island

Data Source Object

data types

definition

document element

document entity

Document Object Model (DOM)

document type declaration

Document Type Definition (DTD)

DOM

DTD

E

EDI

Electronic Data Interchange (EDI)

element

entity

entity reference

Extensible Markup Language (XML)

Extensible Stylesheet Language (XSL)

F

facet

G

H

I

infoset

invalid document

J

K

L

M

mixed content

N

namespace

notation

notation declaration

O

P

parsed entity

processing instruction

Q

R

reference node

replacement text

S

SAX

schema

schema structures

SGML

Simple API for XML (SAX)

simple data type

Simple Object Access Protocol (SOAP)

SOAP

Standard Generalized Markup Language (SGML)

T

template

tokenized attribute type

U

Uniform Resource Identifier (URI)

Uniform Resource Locator (URL)

Uniform Resource Name (URN)

unparsed entity

URI

URL

URN

V

valid

vocabulary

W

W3C

well-formed XML

Worldwide Web Consortium (W3C)

X

XML

XML-Data

XML declaration

XML document

XML engine

XML information set

XML Object Model

XML parser

XPath

XML Pointer Language (XPointer)

XML Query Language (XQL)

XML Schema

XML vocabulary

Xpointer

XQL

XSL

XSL Formatting Objects

XSL Patterns

XSL Transformations (XSLT)

Y

Z

Terms and Definitions

attribute

An XML structural construct. A name-value pair, separated by an equals sign, included inside a tagged element that modifies certain features of the element. All attribute values, including things like size and width, are in fact text strings and not numbers. For XML, all values must be enclosed in quotation marks.
You can declare attributes for an XML element type using an attribute list declaration.

Return to top

Cascading Style Sheets (CSS)

Formatting descriptions that provide augmented control over presentation and layout of HTML and XML elements. CSS can be used for describing the formatting behavior of simply structured XML documents, but does not provide a display structure that deviates from the structure of the source data. See also Extensible Stylesheet Language.

Return to top

CDF

See Channel Definition Format (CDF).

Return to top

Channel Definition Format (CDF)

An XML-based data format used in Microsoft® Internet Explorer 4.0 and later to describe Active Channel™ content and desktop components.
CDF permits a Web publisher to offer frequently updated collections of information, or channels, enabling automatic delivery to compatible Web clients. The user only needs to choose the channel once, and scheduled deliveries of the channel information will be delivered to the client without further intervention.

Return to top

character data

All the textual content of an element or attribute that is not markup. XML differentiates this plain text from binary data. In the XML OM, character data is stored in text nodes, which are implemented as DOM text objects.

Return to top

complex data type

An element that can contain other elements or attributes. Also known as complex type. Appears as <complexType> in XML documents.

Return to top

CSS

See Cascading Style Sheets (CSS).

Return to top

data island

An XML document (<XML> or <SCRIPT language="XML">). that exists within an HTML page. It allows you to script against the XML document without having to load it through script or through the <OBJECT> tag. Almost anything that can be in a well-formed XML document can be inside a data island.
HTML is used as the primary document or display format, and XML is used to embed data within the document.

Return to top

Data Source Object

Provides a way to bind HTML controls directly to an XML data island. It assists developers in connecting to structured XML data and supplying it to an HTML page by using the data-binding facility of dynamic HTML.
XML Data Source Object allows you to work with data one node at a time, but you can also work with multiple nodes at a time, without having to walk the document tree. It binds the data to specific controls on the page and the controls are automatically populated with data from the Data Source Object.

Return to top

data types

The parts and subparts of an XML schema that are used as the basis of all the larger components in schema.

Return to top

definition

A description used to create simple and complex data types.

Return to top

document element

The element in an XML document that contains all other elements. It is the top-level element of an XML document and must be the first element in the document. There is exactly one document element, no part of which appears in the content of any other element. The document element represents the document as a whole; every other element represents a component of the document.
The terms root element and document element are interchangeable.

Return to top

document entity

The starting point for an XML parser. Unlike other entities, the document entity has no name and cannot be referenced. It is the entity in which the XML declaration and document type declaration can occur.

Return to top

Document Object Model (DOM)

A platform- and language-neutral interface that allows programs and scripts to dynamically access and update the content, structure and style of documents. The Document Object Model provides a standard set of objects for representing HTML and XML documents, a standard model of how these objects can be combined, and a standard interface for accessing and manipulating them. Vendors can support the DOM as an interface to their proprietary data structures and APIs, and content authors can write to the standard DOM interfaces rather than product-specific APIs, thus increasing interoperability on the Web.

Return to top

document type declaration

An XML structural construct. Consists of markup code that indicates the grammar rules, or Document Type Definition (DTD), for the particular class of document. The document type declaration can also point to an external file that contains all or part of the DTD. It must appear following the XML declaration and preceding the document element. The syntax of the document type declaration is <!DOCTYPE content>.

Return to top

Document Type Definition (DTD)

Can accompany a document, essentially defining the rules of the document, such as which elements are present and the structural relationship between the elements. It defines what tags can go in your document, what tags can contain other tags, the number and sequence of the tags, the attributes your tags can have, and optionally, the values those attributes can have.
DTDs help to validate the data when the receiving application does not have a built-in description of the incoming data. The DTD is declared within the document type declaration production of the XML file. With XML, however, DTDs are optional.
See also schema.

Return to top

DOM

See Document Object Model.

Return to top

DTD

See Document Type Definition.

Return to top

EDI

See Electronic Data Interchange.

Return to top

Electronic Data Interchange (EDI)

An existing format used to exchange data and support transactions. EDI transactions can be conducted only between sites that have been specifically set up with compatible systems. Proprietary EDI formats are more difficult to write than XML, and unlike XML, cannot be transmitted over HTTP.

Return to top

element

An XML structural construct. An XML element consists of a start tag, an end tag, and the information between the tags, which is often referred to as the contents. Each element has a type, identified by name, sometimes called its "generic identifier" (GI), and may have a set of attribute specifications. Each attribute specification has a name and a value. An instance of an element is declared using <element> tags.
Elements used in an XML file are described by a DTD or schema, either of which can provide a description of the structure of the data.

Return to top

entity

An XML structural construct. A file, database record, or another item that contains data. The primary purpose of an entity is to hold content—not structure, rules, or grammar. Each entity is identified by a unique name and contains its own content, from a single character inside the document to a large file that exists outside the document. The function of an XML entity is similar to that of a macro definition.
The entity can be referred to by an entity reference to insert the entity's contents into the tree at that point. Entity declarations occur in the DTD.

Return to top

entity reference

An XML structural construct. Acts as a placeholder for the content author, and the XML parser places the actual content at each reference site. To include an entity reference, you first insert an ampersand (&) and then enter the entity name followed by a semicolon (;), as follows: &YourEntityName;. Then, when the line is processed, the entity will be replaced with the entity's content.
It is used in much the same way as a macro.

Return to top

Extensible Markup Language (XML)

A subset of SGML that is optimized for delivery over the Web, XML provides a uniform method for describing and exchanging structured data that is independent of applications or vendors.
The key is that with XML, the information is in the document, while the rendering instructions are elsewhere. In other words, content and presentation are separate. XML is the Web's language for data interchange and HTML is the Web's language for rendering.
At the time of this writing, XML 1.0 is a Worldwide Web Consortium Recommendation, which means that it is in the final stage of the approval process.

Return to top

Extensible Stylesheet Language (XSL)

A language used to transform XML-based data into HTML or other presentation formats, for display in a Web browser. The transformation of XML into formats, such as HTML, is done in a declarative way, making it often easier and more accessible than through scripting. In addition, XSL uses XML as its syntax, freeing XML authors from having to learn another markup language.
In contrast to CSS, which "decorates" the XML tree with formatting properties, XSL transforms the XML tree into a new tree (the HTML), allowing extensive reordering, generated text, and calculations—all without modification to the XML source. The source can be maintained from the perspective of "pure content" and can simultaneously be delivered to different channels or target audiences by just switching style sheets.
XSL consists of two parts, a vocabulary for transformation and the XSL Formatting Objects.

Return to top

facet

A restriction on a data type. A single defining aspect of value space. There are two types of facets: fundamental and constraining.

Return to top

infoset

See XML information set.

Return to top

invalid document

Documents that do not follow the XML tag rules. If a document has a DTD or schema, and it doesn't follow the rules defined in its DTD or schema, that document is invalid as well.

Return to top

mixed content

Element types with mixed content are allowed to hold either character data alone or character data interspersed with child elements. In this case, the types of the child elements can be constrained, but not their order or their number of occurrences.

Return to top

namespace

A mechanism that allows developers to uniquely qualify the element names and relationships and to make these names recognizable. By doing so, they can avoid name collisions on elements that have the same name but are defined in different vocabularies. They allow tags from multiple namespaces to be mixed, which is essential if data is coming from multiple sources. Namespaces ensure that element names do not conflict, and clarify who defined which term.
A namespace identifies an XML vocabulary defined within a URN. An attribute on an element, attribute, or entity reference associates a short name with the URN that defines the namespace; that short name is then used as a prefix to the element, attribute, or entity reference name to uniquely identify the namespace. Namespace references have scope. All child nodes beneath the node that specifies the namespace inherit that namespace. This allows nonqualified names to use the default namespace. See also RDF namespace.

Return to top

notation

Tells the parser what type of object is being referenced. Usually refers to a data format of non-XML data, such as BMP. A notation identifies by name the format of unparsed entities, the format of elements that bear a notation attribute, or the application to which a processing instruction is addressed.

Return to top

notation declaration

Tells the parser how to deal with a specific binary file type, as well as provides a name and an external identifier for a notation.
The notation declaration gives an internal name to an existing notation so that it can be referred to in attribute list declarations, unparsed entity declarations, and processing instructions.
The external identifier is used for the notation, which can allow an XML parser or its client application to locate a helper application capable of processing data in the given notation.

Return to top

parsed entity

An entity that has content that is parsed and replaced with actual literal values. The result is called the replacement text. Parsed entities can only contain character data or XML markup.

Return to top

processing instruction

An XML structural construct. A mechanism for embedding information in a file intended for proprietary applications rather than the XML parser or browser. The XML parser passes the instructions to the application.
A processing instruction is a string of text included almost anywhere in an XML document's character data between <? and ?> marks. It begins with the name of the application for which the PI is intended, followed by the data for the instruction.
An example is the XML declaration that begins every valid XML file:

<?xml version="1.0" standalone="yes" ?>

Return to top

reference node

The reference node for a search context is the node that is the immediate parent of all nodes in the search context. Every search context has an associated reference node.

Return to top

replacement text

The content of parsed entities, after replacement of character references and parameter-entity references.

Return to top

SAX

See Simple API for XML.

Return to top

schema

A formal specification of element names that indicates which elements are allowed in an XML document, and in what combinations. It also defines the structure of the document: which elements are child elements of others, the sequence in which the child elements can appear, and the number of child elements. It defines whether an element is empty or can include text. The schema can also define default values for attributes.
A schema is functionally equivalent to a DTD, but is written in XML. A schema also provides for extended functionality such as data typing, inheritance, and presentation rules. Consequently, the new schema languages are far more powerful than DTDs.

Return to top

schema structures

The compounds that can be constructed from data types and are used to describe the element, attribute, and validation structure of a document type.

Return to top

SGML

See Standard Generalized Markup Language.

Return to top

Simple API for XML (SAX)

An XML API that allows developers to take advantage of event-driven XML parsing. Unlike the DOM specification, SAX doesn't require the entire XML file to be loaded into memory. SAX notifies you when certain events happen as it parses your document. When you respond to an event, any data you don't specifically store is discarded. If your document is very large, using SAX will save significant amounts of memory when compared to using DOM. This is especially true if you only need a few elements in a large document.

Return to top

simple data type

An element that contain only text. Also known as simple type. Appears as <simpleType> in XML documents. Attributes are considered simple types because they contain only text.

Return to top

Simple Object Access Protocol (SOAP)

An open, extensible way for applications to communicate using XML-based messages over the Web, regardless of what operating system, object model, or language they use. SOAP provides a way to use the existing Internet infrastructure to enable applications to communicate directly with each other without being unintentionally blocked by firewalls.

Return to top

SOAP

See Simple Object Access Protocol.

Return to top

Standard Generalized Markup Language (SGML)

The international standard for defining descriptions of structure and content of electronic documents. Despite its name, SGML is not a language in itself, but a way of defining languages that are developed along its general principles. SGML defines the way that a markup language is built by specifying the syntax and definitions for the elements and attributes that compose it.
XML is a subset of SGML designed to deliver SGML-type information over the Web, while HTML is an application of SGML.

Return to top

template

The basis of the XML style sheet is the template rule, which makes a template that allows a user agent to construct a styled Result node from a Source node. The template has two parts:
The matching part identifies the source (XML) node to which the processing action is to be applied. The matching information is contained in the match attribute.
The processing part defines how the children are to be processed and what styling is to be applied to them. The processing information is contained in the template's child elements.

Return to top

tokenized attribute type

In a tokenized type, the parser will normalize all white space to a single space character and will eliminate leading and trailing white space altogether. It will also validate the contents based on the declared type.
Seven attribute types are characterized as tokenized types because each value represents either a single token (ID, IDREF, ENTITY, NMTOKEN) or a list of tokens (IDREFS, ENTITIES, and NMTOKENS).

Return to top

Uniform Resource Identifier (URI)

A superclass that includes both URNs and URLs. Presently, URI means URL in nearly all cases when discussing XML, although it is expected that URNs will become more numerous in the future. The URI supplies a universally unique number or name that can identify an element or attribute in a universally unique way.
URIs are a slightly more general scheme for locating resources on the Internet that focuses a more on the resource and less on the location. In theory, a URI could find the closest copy of a mirrored document or locate a document moved from one site to another.

Return to top

Uniform Resource Locator (URL)

The set of URI schemes that have explicit instructions on how to access the resource on the Internet.
URLs are uniform in that they have the same basic syntax no matter what specific type of resource (Web page, newsgroup) is being addressed or what mechanism is described to fetch it.

Return to top

Uniform Resource Name (URN)

Identifies a persistent Internet resource. A URN can provide a mechanism for locating and retrieving a schema file that defines a particular namespace. While an ordinary URL could provide similar functionality, a URN is more robust and easier to manage for this purpose because a URN can refer to more than one URL.
Unlike URLs, URNs are not location-dependent.

Return to top

unparsed entity

Any block of non-XML data, sometimes referred to as a binary entity because its content is often a binary file (such as an image) that is not directly interpreted by the XML parser. An unparsed entity could contain plain text, so the term binary is a bit misleading.
Unlike a parsed entity, an unparsed entity requires a notation, which identifies the format or type of resource to which the entity is declared. Beyond a requirement that an XML parser make the identifiers for the entity and notation available to the application, XML places no constraints on the contents of unparsed entities.

Return to top

URI

See Uniform Resource Identifier.

Return to top

URL

See Uniform Resource Locator.

Return to top

URN

See Uniform Resource Name.

Return to top

valid XML

XML that conforms to the rules defined in the XML specification, as well as the rules defined in the DTD or schema.
The parser must understand the validity constraints of the XML specification and check the document for possible violations. If the parser finds any errors, it must report them to the XML application. The parser must also read the DTD, validate the document against it, and again report any violations to the XML application.
Because all of this parsing and checking can take time and because validation might not always be necessary, XML supports the notion of the well-formed document.

Return to top

vocabulary

See XML vocabulary.

Return to top

W3C

See Worldwide Web Consortium.

Return to top

well-formed XML

XML that follows the XML tag rules listed in the W3C Recommendation for XML 1.0, but doesn't have a DTD or schema. A well-formed XML document contains one or more elements; it has a single document element, with any other elements properly nested under it; and each of the parsed entities referenced directly or indirectly within the document is well formed.
Well-formed XML documents are easy to create because they don't require the additional work of creating a DTD. Well-formed XML can save download time because the client does not need to download the DTD, and it can save processing time because the XML parser doesn't need to process the DTD.

Return to top

Worldwide Web Consortium (W3C)

A standards body located at MIT that sets standards for XML, HTML, XSL, and many other Web technologies.

Return to top

XML

See Extensible Markup Language.

Return to top

XML-Data

A language used to create a schema, which identifies the structure and constraints of a particular XML document. XML-Data carries out the same basic tasks as DTD, but with more power and flexibility. Unlike DTD, which requires its own language and syntax, XML-Data uses XML syntax for its language.

Return to top

XML declaration

The first line of an XML file can optionally contain the "xml" processing instruction, which is known as the XML declaration. The XML declaration can contain pseudo-attributes to indicate the XML language version, the character set, and whether the document can be used as a standalone entity.
An example is the XML declaration that begins every valid XML file:

<?xml version="1.0" standalone="yes" ?>

Return to top

XML document

A document object that is well formed, according to the XML recommendation, and that might (or might not) be valid. The XML document has a logical structure (composed of declarations, elements, comments, character references, and processing instructions) and a physical structure (composed of entities, starting with the root, or document entity).

Return to top

XML engine

Software that supports XML functionality on the client; Internet Explorer 4.0 and later include XML engines. Its components include the XML parser, the XSL processor, and schema support.

Return to top

XML information set

A description of the information available in a well-formed XML document.

Return to top

XML Object Model

An API that defines a standard way in which developers can interact with the elements of the XML structured tree. The XML object model exposes properties, methods, and the actual content (data) contained in an object. It controls how users communicate with trees, and exposes all tree elements as objects, which can be accessed without any return trips to the server. The XML OM uses the W3C standard Document Object Model.

Return to top

XML parser

A software module used to read XML documents and provide access to their content and structure. The XML parser generates a hierarchically structured tree, then hands off data to viewers and other applications for processing, and finally returns the results to the browser. A validating XML parser also checks the XML syntax and reports errors.

Return to top

XPath

The result of an effort to provide a common syntax and semantics for functionality shared between XSL Transformations (XSLT) and XPointer. The primary purpose of XPath is to address parts of an XML document. It also provides basic facilities for manipulation of strings, numbers, and Booleans. XPath uses a compact, non-XML syntax to facilitate use of XPath within URIs and XML attribute values. XPath gets its name from its use of a path notation as used in URLs for navigating through the hierarchical structure of an XML document.

Return to top

XML Pointer Language (XPointer)

A W3C initiative that specifies constructs for addressing the internal structures of XML documents. In particular, it provides for specific reference to elements, character strings, and other parts of XML documents, whether or not they bear an explicit ID attribute.
An XPointer consists of a series of location terms, each of which specifies a location, usually relative to the location specified by the prior location term. Each location term has a keyword (such as id, child, ancestor, and so on) and can have arguments, such as an instance number, element type, or attribute. For example, the XPointer:

child(2,precocious)
refers to the second child element whose type is precocious.

Return to top

XML Query Language (XQL)

A set of extensions to XSL Patterns proposed to the W3C.
XQL is an extension to the capabilities of XSL that will provide for searching into, and data retrieval from, XML documents. It provides ways to manipulate XML in order to create new documents, to control the content of existing documents, and to manage the ordering and presentation of these documents along with XSL.

Return to top

XML Schema

See schema.

Return to top

XML vocabulary

A set of actual elements and the structure for a specific document type used in particular data formats. Vocabularies, along with the structural relationships between the elements, are defined in a DTD that serves as the rulebook for that vocabulary.
One of the first and probably most well-know vocabularies is the Channel Definition Format used to define Web pages that are designed to be sent automatically, or "pushed" to client users.

Return to top

XPointer

See XML Pointer Language.

Return to top

XQL

See XML Query Language.

Return to top

XSL

See Extensible Stylesheet Language.

Return to top

XSL formatting objects

A set of formatting semantics expressed as an XML vocabulary.
Conceptually, these objects form a tree. The formatting objects denote typographic elements such as page, paragraph, rule, and so forth. Finer control over the presentation of these elements is provided by a set of formatting properties, such as indents; word- and letter-spacing; and widow, orphan, and hyphenation control. The formatting objects and formatting properties provide the vocabulary for expressing presentation intent.

Return to top

XSL Patterns

Provide a simple query language for identifying nodes in an XML document, based on their type, name, and values, as well as the relationship of the node to other nodes in the document.
Just like XSL, XSL Patterns is a declarative, not procedural, language. That is, its queries specify what should be found in an XML document, not how to find it. This provides the application with much more flexibility to determine the most efficient method to use to find a piece of data.
Internet Explorer 5.0 supports XSL Patterns with some of the extensions described in XML Query Language.

Return to top

XSL Transformations (XSLT)

Makes use of the expression language defined by XPath for selecting elements for conditional processing and for generating text.
XSLT provides two "hooks" for extending the language, one hook for extending the set of instruction elements used in templates and one hook for extending the set of functions used in XPath expressions. These hooks are both based on XML namespaces.

Return to top